use crate::de::FromBase32;
use crate::ser::{Base32Iterable, Base32Len};
use crate::{sha256, PayeePubKey, PaymentSecret, PositiveTimestamp, RawDataPart, Sha256};
use bech32::Fe32;
use core::fmt::Debug;
use std::str::FromStr;
fn ser_de_test<T>(o: T, expected_str: &str)
where
T: Base32Iterable + FromBase32 + Eq + Debug,
T::Err: Debug,
{
let serialized_32 = o.fe_iter().collect::<Vec<Fe32>>();
let serialized_str = serialized_32.iter().map(|f| f.to_char()).collect::<String>();
assert_eq!(serialized_str, expected_str, "Mismatch for {:?}", o);
let o2 = T::from_base32(&serialized_32).unwrap();
assert_eq!(o, o2, "Mismatch for {}", serialized_str);
}
fn ser_de_test_len<T>(o: T, expected_str: &str)
where
T: Base32Iterable + Base32Len + FromBase32 + Eq + Debug,
T::Err: Debug,
{
assert_eq!(o.base32_len(), expected_str.len(), "Mismatch for {} {:?}", expected_str, o);
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 array_u8() {
ser_de_test_len([0], "qq");
ser_de_test_len([255], "lu");
ser_de_test_len([0, 1], "qqqs");
ser_de_test_len([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "qqqsyqcyq5rqwzqf");
ser_de_test_len([255, 254, 253, 252, 251, 250, 249, 248, 247, 246], "lll0ml8mltul3alk");
}
#[test]
fn array_u8_error_invalid_length() {
assert_eq!(
<[u8; 3]>::from_base32(
&"pqqql".to_string().chars().map(|c| Fe32::from_char(c).unwrap()).collect::<Vec<_>>()[..]
)
.unwrap(),
[8, 0, 15]
);
assert_eq!(
<[u8; 3]>::from_base32(
&"pqql".to_string().chars().map(|c| Fe32::from_char(c).unwrap()).collect::<Vec<_>>()[..]
)
.err()
.unwrap()
.to_string(),
"Slice had length 2 instead of 3 for element <[u8; N]>"
);
assert_eq!(
<[u8; 3]>::from_base32(
&"pqqqqql".to_string().chars().map(|c| Fe32::from_char(c).unwrap()).collect::<Vec<_>>()
[..]
)
.err()
.unwrap()
.to_string(),
"Slice had length 4 instead of 3 for element <[u8; N]>"
);
}
#[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;
ser_de_test_len(
Bolt11InvoiceFeatures::from_le_bytes(vec![1, 2, 3, 4, 5, 42, 100, 101]),
"x2ep2q5zqxqsp",
);
ser_de_test_len(Bolt11InvoiceFeatures::from_le_bytes(vec![]), "");
ser_de_test_len(Bolt11InvoiceFeatures::from_le_bytes(vec![0]), "");
ser_de_test_len(Bolt11InvoiceFeatures::from_le_bytes(vec![1]), "p");
ser_de_test_len(Bolt11InvoiceFeatures::from_le_bytes(vec![31]), "l");
ser_de_test_len(Bolt11InvoiceFeatures::from_le_bytes(vec![100]), "ry");
ser_de_test_len(Bolt11InvoiceFeatures::from_le_bytes(vec![255]), "8l");
ser_de_test_len(Bolt11InvoiceFeatures::from_le_bytes(vec![1]), "p");
ser_de_test_len(Bolt11InvoiceFeatures::from_le_bytes(vec![1, 2]), "sp");
ser_de_test_len(Bolt11InvoiceFeatures::from_le_bytes(vec![1, 2, 3]), "xqsp");
ser_de_test_len(Bolt11InvoiceFeatures::from_le_bytes(vec![1, 2, 3, 4]), "zqxqsp");
ser_de_test_len(Bolt11InvoiceFeatures::from_le_bytes(vec![1, 2, 3, 4, 5]), "5zqxqsp");
ser_de_test_len(
Bolt11InvoiceFeatures::from_le_bytes(vec![255, 254, 253, 252, 251]),
"l070mlhl",
);
ser_de_test_len(Bolt11InvoiceFeatures::from_le_bytes(vec![100, 0]), "ry");
ser_de_test_len(Bolt11InvoiceFeatures::from_le_bytes(vec![100, 0, 0, 0]), "ry");
ser_de_test_len(Bolt11InvoiceFeatures::from_le_bytes(vec![0, 100]), "eqq");
ser_de_test_len(Bolt11InvoiceFeatures::from_le_bytes(vec![0, 0, 0, 100]), "pjqqqqq");
ser_de_test_len(
Bolt11InvoiceFeatures::from_le_bytes(vec![255, 255, 255, 255, 255, 255, 255, 255, 255]),
"rllllllllllllll",
);
ser_de_test_len(
Bolt11InvoiceFeatures::from_le_bytes(vec![255, 255, 255, 255, 255, 255, 255, 255, 254]),
"rl0llllllllllll",
);
ser_de_test_len(
Bolt11InvoiceFeatures::from_le_bytes(vec![255, 255, 255, 255, 255, 255, 255, 255, 127]),
"pllllllllllllll",
);
ser_de_test_len(
Bolt11InvoiceFeatures::from_le_bytes(vec![255, 255, 255, 255, 255, 255, 255, 255, 63]),
"llllllllllllll",
);
assert_eq!(
Bolt11InvoiceFeatures::from_base32(
&"qqqqqry".to_string().chars().map(|c| Fe32::from_char(c).unwrap()).collect::<Vec<_>>()
[..]
)
.unwrap()
.le_flags(),
vec![100]
);
assert_eq!(
Bolt11InvoiceFeatures::from_base32(
&"ry".to_string().chars().map(|c| Fe32::from_char(c).unwrap()).collect::<Vec<_>>()[..]
)
.unwrap()
.le_flags(),
vec![100]
);
}
#[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(&[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",
);
}