]> git.bitcoin.ninja Git - rust-lightning/commitdiff
Add invoice serialization tests
authoroptout <13562139+optout21@users.noreply.github.com>
Fri, 23 Aug 2024 13:46:22 +0000 (15:46 +0200)
committeroptout <13562139+optout21@users.noreply.github.com>
Fri, 23 Aug 2024 13:46:22 +0000 (15:46 +0200)
lightning-invoice/src/lib.rs
lightning-invoice/src/test_ser_de.rs [new file with mode: 0644]

index 58f08583ad25d4abc1c8b4f403bf8af7d8a67b48..08b670f41fef8cbadb649a9df3aca913add9c146 100644 (file)
@@ -64,6 +64,9 @@ mod de;
 mod ser;
 mod tb;
 
+#[cfg(test)]
+mod test_ser_de;
+
 #[allow(unused_imports)]
 mod prelude {
        pub use alloc::{vec, vec::Vec, string::String};
diff --git a/lightning-invoice/src/test_ser_de.rs b/lightning-invoice/src/test_ser_de.rs
new file mode 100644 (file)
index 0000000..2025d4a
--- /dev/null
@@ -0,0 +1,183 @@
+use crate::{
+       sha256, FromBase32, PayeePubKey, PaymentSecret, PositiveTimestamp, RawDataPart, Sha256,
+};
+use bech32::{Base32Len, ToBase32};
+
+use core::fmt::Debug;
+use std::str::FromStr;
+
+/// Test base32 encode and decode
+fn ser_de_test<T>(o: T, expected_str: &str)
+where
+       T: ToBase32 + FromBase32 + Eq + Debug,
+       T::Err: Debug,
+{
+       let serialized_32 = o.to_base32();
+       let serialized_str = serialized_32.iter().map(|f| f.to_char()).collect::<String>();
+       assert_eq!(serialized_str, expected_str);
+
+       // deserialize back
+       let o2 = T::from_base32(&serialized_32).unwrap();
+       assert_eq!(o, o2);
+}
+
+/// Test base32 encode and decode, and also length hint
+fn ser_de_test_len<T>(o: T, expected_str: &str)
+where
+       T: ToBase32 + FromBase32 + Base32Len + Eq + Debug,
+       T::Err: Debug,
+{
+       assert_eq!(o.base32_len(), expected_str.len());
+
+       ser_de_test(o, expected_str)
+}
+
+#[test]
+fn vec_u8() {
+       ser_de_test_len(vec![0], "qq");
+       ser_de_test_len(vec![255], "lu");
+       ser_de_test_len(vec![0, 1], "qqqs");
+       ser_de_test_len(vec![0, 1, 2], "qqqsy");
+       ser_de_test_len(vec![0, 1, 2, 3], "qqqsyqc");
+       ser_de_test_len(vec![0, 1, 2, 3, 4], "qqqsyqcy");
+       ser_de_test_len(vec![0, 1, 2, 3, 4, 5], "qqqsyqcyq5");
+       ser_de_test_len(vec![0, 1, 2, 3, 4, 5, 6], "qqqsyqcyq5rq");
+       ser_de_test_len(vec![0, 1, 2, 3, 4, 5, 6, 7], "qqqsyqcyq5rqw");
+       ser_de_test_len(vec![0, 1, 2, 3, 4, 5, 6, 7, 8], "qqqsyqcyq5rqwzq");
+       ser_de_test_len(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "qqqsyqcyq5rqwzqf");
+       ser_de_test_len(vec![9, 8, 7, 6, 5, 4, 3, 2, 1, 0], "pyyqwps9qspsyqgq");
+       ser_de_test_len(vec![255, 254, 253, 252, 251, 250, 249, 248, 247, 246], "lll0ml8mltul3alk");
+}
+
+#[test]
+fn payment_secret() {
+       let payment_secret = PaymentSecret([7; 32]);
+       ser_de_test_len(payment_secret, "qurswpc8qurswpc8qurswpc8qurswpc8qurswpc8qurswpc8qurs");
+}
+
+#[test]
+fn positive_timestamp() {
+       use crate::PositiveTimestamp;
+
+       let timestamp = PositiveTimestamp::from_unix_timestamp(10000).unwrap();
+       ser_de_test(timestamp, "qqqqfcs");
+}
+
+#[test]
+fn bolt11_invoice_features() {
+       use crate::Bolt11InvoiceFeatures;
+
+       let features = Bolt11InvoiceFeatures::from_le_bytes(vec![1, 2, 3, 4, 5, 42, 100, 101]);
+       ser_de_test_len(features, "x2ep2q5zqxqsp");
+}
+
+#[test]
+fn raw_tagged_field() {
+       use crate::TaggedField::PaymentHash;
+
+       let field = PaymentHash(Sha256(
+               sha256::Hash::from_str("0001020304050607080900010203040506070809000102030405060708090102")
+                       .unwrap(),
+       ));
+       ser_de_test(field, "pp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypq");
+}
+
+#[test]
+fn sha256() {
+       let hash = Sha256(
+               sha256::Hash::from_str("0001020304050607080900010203040506070809000102030405060708090102")
+                       .unwrap(),
+       );
+       ser_de_test_len(hash, "qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypq");
+}
+
+#[test]
+fn description() {
+       use crate::Description;
+
+       let description =
+               Description::new("This is a looooong        description".to_string()).unwrap();
+       ser_de_test_len(description, "235xjueqd9ejqcfqd3hk7mm0dahxwgpqyqszqgpqypjx2umrwf5hqarfdahq");
+}
+
+#[test]
+fn raw_data_part() {
+       use crate::TaggedField::PaymentHash;
+
+       let raw_data_part = RawDataPart {
+               timestamp: PositiveTimestamp::from_unix_timestamp(10000).unwrap(),
+               tagged_fields: vec![PaymentHash(Sha256(
+                       sha256::Hash::from_str(
+                               "0001020304050607080900010203040506070809000102030405060708090102",
+                       )
+                       .unwrap(),
+               ))
+               .into()],
+       };
+       ser_de_test(raw_data_part, "qqqqfcspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypq");
+}
+
+#[test]
+fn payeepubkey() {
+       use bitcoin::key::Secp256k1;
+       use bitcoin::secp256k1::{PublicKey, SecretKey};
+
+       let secp = Secp256k1::new();
+       let dummy_secret_key = SecretKey::from_slice(&[1; 32]).unwrap();
+       let payee_pub_key = PayeePubKey(PublicKey::from_secret_key(&secp, &dummy_secret_key));
+       ser_de_test_len(payee_pub_key, "qvdcf32k0vfxgsyet5ldt246q4jaw8scx3sysx0lnstlt6w4m5rc7");
+}
+
+#[test]
+fn expiry_time() {
+       use crate::ExpiryTime;
+
+       let expiry = ExpiryTime::from_seconds(10000);
+       ser_de_test_len(expiry, "fcs");
+}
+
+#[test]
+fn min_final_cltv_expiry_delta() {
+       use crate::MinFinalCltvExpiryDelta;
+
+       let cltv_delta = MinFinalCltvExpiryDelta(124);
+       ser_de_test_len(cltv_delta, "ru");
+}
+
+#[test]
+fn fallback() {
+       use crate::{Fallback, PubkeyHash, ScriptHash, WitnessVersion};
+       use bitcoin::hashes::Hash;
+
+       {
+               let fallback = Fallback::PubKeyHash(PubkeyHash::from_slice(&[3; 20]).unwrap());
+               ser_de_test_len(fallback, "3qvpsxqcrqvpsxqcrqvpsxqcrqvpsxqcr");
+       }
+       {
+               let fallback = Fallback::ScriptHash(ScriptHash::from_slice(&[3; 20]).unwrap());
+               ser_de_test_len(fallback, "jqvpsxqcrqvpsxqcrqvpsxqcrqvpsxqcr");
+       }
+       {
+               let fallback =
+                       Fallback::SegWitProgram { version: WitnessVersion::V0, program: vec![3; 20] };
+               ser_de_test_len(fallback, "qqvpsxqcrqvpsxqcrqvpsxqcrqvpsxqcr");
+       }
+}
+
+#[test]
+fn private_route() {
+       use crate::{PrivateRoute, PublicKey, RouteHint, RouteHintHop, RoutingFees};
+
+       let private_route = PrivateRoute(RouteHint(vec![RouteHintHop {
+               src_node_id: PublicKey::from_slice(&vec![2; 33]).unwrap(),
+               short_channel_id: 0x0102030405060708,
+               fees: RoutingFees { base_msat: 1, proportional_millionths: 20 },
+               cltv_expiry_delta: 3,
+               htlc_minimum_msat: None,
+               htlc_maximum_msat: None,
+       }]));
+       ser_de_test_len(
+               private_route,
+               "qgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqgzqvzq2ps8pqqqqqqpqqqqq9qqqv",
+       );
+}