use proptest::prelude::*;
use crate::{
sapling::{self, OutputInTransactionV4, PerSpendAnchor, SharedAnchor},
serialization::{ZcashDeserializeInto, ZcashSerialize},
};
proptest! {
#[test]
fn spend_v4_roundtrip(
spend in any::<sapling::Spend<PerSpendAnchor>>(),
) {
let _init_guard = zebra_test::init();
let data = spend.zcash_serialize_to_vec().expect("spend should serialize");
let spend_parsed = data.zcash_deserialize_into().expect("randomized spend should deserialize");
prop_assert_eq![&spend, &spend_parsed];
let data2 = spend_parsed
.zcash_serialize_to_vec()
.expect("vec serialization is infallible");
prop_assert_eq![data, data2, "data must be equal if structs are equal"];
}
#[test]
fn spend_v5_roundtrip(
spend in any::<sapling::Spend<SharedAnchor>>(),
) {
let _init_guard = zebra_test::init();
let (prefix, zkproof, spend_auth_sig) = spend.into_v5_parts();
let data = prefix.zcash_serialize_to_vec().expect("spend prefix should serialize");
let parsed = data.zcash_deserialize_into().expect("randomized spend prefix should deserialize");
prop_assert_eq![&prefix, &parsed];
let data2 = parsed
.zcash_serialize_to_vec()
.expect("vec serialization is infallible");
prop_assert_eq![data, data2, "data must be equal if structs are equal"];
let data = zkproof.zcash_serialize_to_vec().expect("spend zkproof should serialize");
let parsed = data.zcash_deserialize_into().expect("randomized spend zkproof should deserialize");
prop_assert_eq![&zkproof, &parsed];
let data2 = parsed
.zcash_serialize_to_vec()
.expect("vec serialization is infallible");
prop_assert_eq![data, data2, "data must be equal if structs are equal"];
let data = spend_auth_sig.zcash_serialize_to_vec().expect("spend auth sig should serialize");
let parsed = data.zcash_deserialize_into().expect("randomized spend auth sig should deserialize");
prop_assert_eq![&spend_auth_sig, &parsed];
let data2 = parsed
.zcash_serialize_to_vec()
.expect("vec serialization is infallible");
prop_assert_eq![data, data2, "data must be equal if structs are equal"];
}
#[test]
fn output_roundtrip(
output in any::<sapling::Output>(),
) {
let _init_guard = zebra_test::init();
let data = output.clone().into_v4().zcash_serialize_to_vec().expect("output should serialize");
let output_parsed = data.zcash_deserialize_into::<OutputInTransactionV4>().expect("randomized output should deserialize").into_output();
prop_assert_eq![&output, &output_parsed];
let data2 = output_parsed
.into_v4()
.zcash_serialize_to_vec()
.expect("vec serialization is infallible");
prop_assert_eq![data, data2, "data must be equal if structs are equal"];
let (prefix, zkproof) = output.into_v5_parts();
let data = prefix.zcash_serialize_to_vec().expect("output prefix should serialize");
let parsed = data.zcash_deserialize_into().expect("randomized output prefix should deserialize");
prop_assert_eq![&prefix, &parsed];
let data2 = parsed
.zcash_serialize_to_vec()
.expect("vec serialization is infallible");
prop_assert_eq![data, data2, "data must be equal if structs are equal"];
let data = zkproof.zcash_serialize_to_vec().expect("output zkproof should serialize");
let parsed = data.zcash_deserialize_into().expect("randomized output zkproof should deserialize");
prop_assert_eq![&zkproof, &parsed];
let data2 = parsed
.zcash_serialize_to_vec()
.expect("vec serialization is infallible");
prop_assert_eq![data, data2, "data must be equal if structs are equal"];
}
}
proptest! {
#[test]
fn sapling_shielded_data_v4_roundtrip(
shielded_v4 in any::<sapling::ShieldedData<PerSpendAnchor>>(),
) {
let _init_guard = zebra_test::init();
let data = shielded_v4.zcash_serialize_to_vec().expect("shielded_v4 should serialize");
let shielded_v4_parsed: Option<sapling::ShieldedData<PerSpendAnchor>> = data.zcash_deserialize_into()
.expect("randomized shielded_v4 should deserialize");
if let Some(shielded_v4_parsed) = shielded_v4_parsed {
prop_assert_eq![&shielded_v4, &shielded_v4_parsed];
let data2 = shielded_v4_parsed
.zcash_serialize_to_vec()
.expect("vec serialization is infallible");
prop_assert_eq![data, data2, "data must be equal if structs are equal"];
} else {
panic!("unexpected parsing error: ShieldedData should be Some(_)");
}
}
#[test]
fn sapling_shielded_data_v5_roundtrip(
shielded_v5 in any::<sapling::ShieldedData<SharedAnchor>>(),
) {
let _init_guard = zebra_test::init();
let data = shielded_v5.zcash_serialize_to_vec().expect("shielded_v5 should serialize");
let shielded_v5_parsed = data.zcash_deserialize_into().expect("randomized shielded_v5 should deserialize");
if let Some(shielded_v5_parsed) = shielded_v5_parsed {
prop_assert_eq![&shielded_v5,
&shielded_v5_parsed];
let data2 = shielded_v5_parsed
.zcash_serialize_to_vec()
.expect("vec serialization is infallible");
prop_assert_eq![data, data2, "data must be equal if structs are equal"];
} else {
panic!("unexpected parsing error: ShieldedData should be Some(_)");
}
}
#[test]
fn sapling_shielded_data_v4_outputs_only(
shielded_v4 in any::<sapling::ShieldedData<PerSpendAnchor>>(),
) {
let _init_guard = zebra_test::init();
prop_assume!(shielded_v4.outputs().count() > 0);
let mut shielded_v4 = shielded_v4;
let outputs: Vec<_> = shielded_v4.outputs().cloned().collect();
shielded_v4.transfers = sapling::TransferData::JustOutputs {
outputs: outputs.try_into().unwrap(),
};
let data = shielded_v4.zcash_serialize_to_vec().expect("shielded_v4 should serialize");
let shielded_v4_parsed: Option<sapling::ShieldedData<PerSpendAnchor>> = data.zcash_deserialize_into()
.expect("randomized shielded_v4 should deserialize");
if let Some(shielded_v4_parsed) = shielded_v4_parsed {
prop_assert_eq![&shielded_v4, &shielded_v4_parsed];
let data2 = shielded_v4_parsed
.zcash_serialize_to_vec()
.expect("vec serialization is infallible");
prop_assert_eq![data, data2, "data must be equal if structs are equal"];
} else {
panic!("unexpected parsing error: ShieldedData should be Some(_)");
}
}
#[test]
fn sapling_shielded_data_v5_outputs_only(
shielded_v5 in any::<sapling::ShieldedData<SharedAnchor>>(),
) {
let _init_guard = zebra_test::init();
prop_assume!(shielded_v5.outputs().count() > 0);
let mut shielded_v5 = shielded_v5;
let outputs: Vec<_> = shielded_v5.outputs().cloned().collect();
shielded_v5.transfers = sapling::TransferData::JustOutputs {
outputs: outputs.try_into().unwrap(),
};
let data = shielded_v5.zcash_serialize_to_vec().expect("shielded_v5 should serialize");
let shielded_v5_parsed = data.zcash_deserialize_into().expect("randomized shielded_v5 should deserialize");
if let Some(shielded_v5_parsed) = shielded_v5_parsed {
prop_assert_eq![&shielded_v5,
&shielded_v5_parsed];
let data2 = shielded_v5_parsed
.zcash_serialize_to_vec()
.expect("vec serialization is infallible");
prop_assert_eq![data, data2, "data must be equal if structs are equal"];
} else {
panic!("unexpected parsing error: ShieldedData should be Some(_)");
}
}
}