//! Tests for trusted preallocation during deserialization. use proptest::{prelude::*, proptest}; use crate::{ block::MAX_BLOCK_BYTES, primitives::{Bctv14Proof, Groth16Proof}, serialization::{arbitrary::max_allocation_is_big_enough, TrustedPreallocate, ZcashSerialize}, sprout::joinsplit::{JoinSplit, BCTV14_JOINSPLIT_SIZE, GROTH16_JOINSPLIT_SIZE}, }; proptest! { /// Confirm that each JoinSplit takes exactly BCTV14_JOINSPLIT_SIZE bytes when serialized. /// This verifies that our calculated [`TrustedPreallocate::max_allocation`] is indeed an upper bound. #[test] fn joinsplit_btcv14_size_is_correct(joinsplit in >::arbitrary_with(())) { let serialized = joinsplit.zcash_serialize_to_vec().expect("Serialization to vec must succeed"); prop_assert!(serialized.len() as u64 == BCTV14_JOINSPLIT_SIZE) } /// Confirm that each JoinSplit takes exactly GROTH16_JOINSPLIT_SIZE bytes when serialized. /// This verifies that our calculated [`TrustedPreallocate::max_allocation`] is indeed an upper bound. #[test] fn joinsplit_groth16_size_is_correct(joinsplit in >::arbitrary_with(())) { let serialized = joinsplit.zcash_serialize_to_vec().expect("Serialization to vec must succeed"); prop_assert!(serialized.len() as u64 == GROTH16_JOINSPLIT_SIZE) } } proptest! { #![proptest_config(ProptestConfig::with_cases(128))] /// Verify that... /// 1. The smallest disallowed vector of `JoinSplit`s is too large to fit in a Zcash block /// 2. The largest allowed vector is small enough to fit in a legal Zcash block #[test] fn joinsplit_btcv14_max_allocation_is_correct(joinsplit in >::arbitrary_with(())) { let ( smallest_disallowed_vec_len, smallest_disallowed_serialized_len, largest_allowed_vec_len, largest_allowed_serialized_len, ) = max_allocation_is_big_enough(joinsplit); // Check that our smallest_disallowed_vec is only one item larger than the limit prop_assert!(((smallest_disallowed_vec_len - 1) as u64) == >::max_allocation()); // Check that our smallest_disallowed_vec is too big to fit in a valid Zcash Block. prop_assert!(smallest_disallowed_serialized_len as u64 > MAX_BLOCK_BYTES); // Check that our largest_allowed_vec contains the maximum number of JoinSplits prop_assert!((largest_allowed_vec_len as u64) == >::max_allocation()); // Check that our largest_allowed_vec is small enough to fit in a Zcash Block. prop_assert!(largest_allowed_serialized_len as u64 <= MAX_BLOCK_BYTES); } /// Verify that... /// 1. The smallest disallowed vector of `JoinSplit`s is too large to fit in a Zcash block /// 2. The largest allowed vector is small enough to fit in a legal Zcash block #[test] fn joinsplit_groth16_max_allocation_is_correct(joinsplit in >::arbitrary_with(())) { let ( smallest_disallowed_vec_len, smallest_disallowed_serialized_len, largest_allowed_vec_len, largest_allowed_serialized_len, ) = max_allocation_is_big_enough(joinsplit); // Check that our smallest_disallowed_vec is only one item larger than the limit prop_assert!(((smallest_disallowed_vec_len - 1) as u64) == >::max_allocation()); // Check that our smallest_disallowed_vec is too big to fit in a valid Zcash Block. prop_assert!(smallest_disallowed_serialized_len as u64 > MAX_BLOCK_BYTES); // Check that our largest_allowed_vec contains the maximum number of JoinSplits prop_assert!((largest_allowed_vec_len as u64) == >::max_allocation()); // Check that our largest_allowed_vec is small enough to fit in a Zcash Block. prop_assert!(largest_allowed_serialized_len as u64 <= MAX_BLOCK_BYTES); } }