Test the manual eq impl on sapling::ShieldedData<PerSpend> (#1989)
This commit is contained in:
parent
375c8d8700
commit
f8094cdf5c
|
@ -86,7 +86,11 @@ proptest! {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return the
|
||||
/// Return the following calculations on `spend`:
|
||||
/// smallest_disallowed_vec_len
|
||||
/// smallest_disallowed_serialized_len
|
||||
/// largest_allowed_vec_len
|
||||
/// largest_allowed_serialized_len
|
||||
fn spend_max_allocation_is_big_enough<AnchorV>(
|
||||
spend: Spend<AnchorV>,
|
||||
) -> (usize, usize, usize, usize)
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
use proptest::prelude::*;
|
||||
|
||||
use super::super::super::transaction::*;
|
||||
use super::super::shielded_data::*;
|
||||
|
||||
use crate::{
|
||||
block,
|
||||
sapling::{self, PerSpendAnchor},
|
||||
serialization::{ZcashDeserializeInto, ZcashSerialize},
|
||||
transaction::{LockTime, Transaction},
|
||||
};
|
||||
|
||||
use futures::future::Either;
|
||||
|
||||
proptest! {
|
||||
// TODO: generalise this test for `ShieldedData<SharedAnchor>` (#1829)
|
||||
#[test]
|
||||
fn shielded_data_roundtrip(shielded in any::<ShieldedData<PerSpendAnchor>>()) {
|
||||
fn shielded_data_roundtrip(shielded in any::<sapling::ShieldedData<PerSpendAnchor>>()) {
|
||||
zebra_test::init();
|
||||
|
||||
// shielded data doesn't serialize by itself, so we have to stick it in
|
||||
|
@ -30,9 +32,70 @@ proptest! {
|
|||
prop_assert_eq![tx, tx_parsed];
|
||||
}
|
||||
|
||||
/// Check that ShieldedData serialization is equal if `shielded1 == shielded2`
|
||||
/// Check that ShieldedData<PerSpendAnchor> is equal when `first` is swapped
|
||||
/// between a spend and an output
|
||||
//
|
||||
// TODO: generalise this test for `ShieldedData<SharedAnchor>` (#1829)
|
||||
#[test]
|
||||
fn shielded_data_serialize_eq(shielded1 in any::<ShieldedData<PerSpendAnchor>>(), shielded2 in any::<ShieldedData<PerSpendAnchor>>()) {
|
||||
fn shielded_data_per_spend_swap_first_eq(shielded1 in any::<sapling::ShieldedData<PerSpendAnchor>>()) {
|
||||
use Either::*;
|
||||
|
||||
zebra_test::init();
|
||||
|
||||
// we need at least one spend and one output to swap them
|
||||
prop_assume!(shielded1.spends().count() > 0 && shielded1.outputs().count() > 0);
|
||||
|
||||
let mut shielded2 = shielded1.clone();
|
||||
let mut spends: Vec<_> = shielded2.spends().cloned().collect();
|
||||
let mut outputs: Vec<_> = shielded2.outputs().cloned().collect();
|
||||
match shielded2.first {
|
||||
Left(_spend) => {
|
||||
shielded2.first = Right(outputs.remove(0));
|
||||
shielded2.rest_outputs = outputs;
|
||||
shielded2.rest_spends = spends;
|
||||
}
|
||||
Right(_output) => {
|
||||
shielded2.first = Left(spends.remove(0));
|
||||
shielded2.rest_spends = spends;
|
||||
shielded2.rest_outputs = outputs;
|
||||
}
|
||||
}
|
||||
|
||||
prop_assert_eq![&shielded1, &shielded2];
|
||||
|
||||
// shielded data doesn't serialize by itself, so we have to stick it in
|
||||
// a transaction
|
||||
let tx1 = Transaction::V4 {
|
||||
inputs: Vec::new(),
|
||||
outputs: Vec::new(),
|
||||
lock_time: LockTime::min_lock_time(),
|
||||
expiry_height: block::Height(0),
|
||||
joinsplit_data: None,
|
||||
sapling_shielded_data: Some(shielded1),
|
||||
};
|
||||
let tx2 = Transaction::V4 {
|
||||
inputs: Vec::new(),
|
||||
outputs: Vec::new(),
|
||||
lock_time: LockTime::min_lock_time(),
|
||||
expiry_height: block::Height(0),
|
||||
joinsplit_data: None,
|
||||
sapling_shielded_data: Some(shielded2),
|
||||
};
|
||||
|
||||
prop_assert_eq![&tx1, &tx2];
|
||||
|
||||
let data1 = tx1.zcash_serialize_to_vec().expect("tx1 should serialize");
|
||||
let data2 = tx2.zcash_serialize_to_vec().expect("tx2 should serialize");
|
||||
|
||||
prop_assert_eq![data1, data2];
|
||||
}
|
||||
|
||||
/// Check that ShieldedData<PerSpendAnchor> serialization is equal if
|
||||
/// `shielded1 == shielded2`
|
||||
//
|
||||
// TODO: generalise this test for `ShieldedData<SharedAnchor>` (#1829)
|
||||
#[test]
|
||||
fn shielded_data_per_spend_serialize_eq(shielded1 in any::<sapling::ShieldedData<PerSpendAnchor>>(), shielded2 in any::<sapling::ShieldedData<PerSpendAnchor>>()) {
|
||||
zebra_test::init();
|
||||
|
||||
let shielded_eq = shielded1 == shielded2;
|
||||
|
@ -56,6 +119,12 @@ proptest! {
|
|||
sapling_shielded_data: Some(shielded2),
|
||||
};
|
||||
|
||||
if shielded_eq {
|
||||
prop_assert_eq![&tx1, &tx2];
|
||||
} else {
|
||||
prop_assert_ne![&tx1, &tx2];
|
||||
}
|
||||
|
||||
let data1 = tx1.zcash_serialize_to_vec().expect("tx1 should serialize");
|
||||
let data2 = tx2.zcash_serialize_to_vec().expect("tx2 should serialize");
|
||||
|
||||
|
@ -65,4 +134,55 @@ proptest! {
|
|||
prop_assert_ne![data1, data2];
|
||||
}
|
||||
}
|
||||
|
||||
/// Check that ShieldedData<PerSpendAnchor> serialization is equal when we
|
||||
/// replace all the known fields.
|
||||
///
|
||||
/// This test checks for extra fields that are not in `ShieldedData::eq`.
|
||||
//
|
||||
// TODO: generalise this test for `ShieldedData<SharedAnchor>` (#1829)
|
||||
#[test]
|
||||
fn shielded_data_per_spend_field_assign_eq(shielded1 in any::<sapling::ShieldedData<PerSpendAnchor>>(), shielded2 in any::<sapling::ShieldedData<PerSpendAnchor>>()) {
|
||||
zebra_test::init();
|
||||
|
||||
let mut shielded2 = shielded2;
|
||||
|
||||
// these fields must match ShieldedData::eq
|
||||
// the spends() and outputs() checks cover first, rest_spends, and rest_outputs
|
||||
shielded2.first = shielded1.first.clone();
|
||||
shielded2.rest_spends = shielded1.rest_spends.clone();
|
||||
shielded2.rest_outputs = shielded1.rest_outputs.clone();
|
||||
// now for the fields that are checked literally
|
||||
shielded2.value_balance = shielded1.value_balance;
|
||||
shielded2.shared_anchor = shielded1.shared_anchor;
|
||||
shielded2.binding_sig = shielded1.binding_sig;
|
||||
|
||||
prop_assert_eq![&shielded1, &shielded2];
|
||||
|
||||
// shielded data doesn't serialize by itself, so we have to stick it in
|
||||
// a transaction
|
||||
let tx1 = Transaction::V4 {
|
||||
inputs: Vec::new(),
|
||||
outputs: Vec::new(),
|
||||
lock_time: LockTime::min_lock_time(),
|
||||
expiry_height: block::Height(0),
|
||||
joinsplit_data: None,
|
||||
sapling_shielded_data: Some(shielded1),
|
||||
};
|
||||
let tx2 = Transaction::V4 {
|
||||
inputs: Vec::new(),
|
||||
outputs: Vec::new(),
|
||||
lock_time: LockTime::min_lock_time(),
|
||||
expiry_height: block::Height(0),
|
||||
joinsplit_data: None,
|
||||
sapling_shielded_data: Some(shielded2),
|
||||
};
|
||||
|
||||
prop_assert_eq![&tx1, &tx2];
|
||||
|
||||
let data1 = tx1.zcash_serialize_to_vec().expect("tx1 should serialize");
|
||||
let data2 = tx2.zcash_serialize_to_vec().expect("tx2 should serialize");
|
||||
|
||||
prop_assert_eq![data1, data2];
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue