Skip to content

Commit

Permalink
Add compact size range and conversion tests
Browse files Browse the repository at this point in the history
  • Loading branch information
teor2345 committed Nov 4, 2021
1 parent 3a28c63 commit dd01bb5
Showing 1 changed file with 43 additions and 11 deletions.
54 changes: 43 additions & 11 deletions zebra-chain/src/serialization/tests/prop.rs
Original file line number Diff line number Diff line change
@@ -1,58 +1,81 @@
//! Property-based tests for basic serialization primitives.
use std::io::Cursor;
use std::{convert::TryFrom, io::Cursor};

use proptest::prelude::*;

use crate::{
serialization::{
CompactSize64, CompactSizeMessage, ZcashDeserialize, ZcashDeserializeInto, ZcashSerialize,
MAX_PROTOCOL_MESSAGE_LEN,
},
transaction::UnminedTx,
};

proptest! {
#[test]
fn compact_size_message_write_then_read_round_trip(s in any::<CompactSizeMessage>()) {
fn compact_size_message_write_then_read_round_trip(size in any::<CompactSizeMessage>()) {
zebra_test::init();

let buf = s.zcash_serialize_to_vec().unwrap();
let buf = size.zcash_serialize_to_vec().unwrap();
// Maximum encoding size of a CompactSize is 9 bytes.
prop_assert!(buf.len() <= 9);

let expect_s: CompactSizeMessage = buf.zcash_deserialize_into().unwrap();
prop_assert_eq!(s, expect_s);
let expect_size: CompactSizeMessage = buf.zcash_deserialize_into().unwrap();
prop_assert_eq!(size, expect_size);

// Also check the range is correct
let size: usize = size.into();
prop_assert!(size <= MAX_PROTOCOL_MESSAGE_LEN);
}

#[test]
fn compact_size_message_read_then_write_round_trip(bytes in prop::array::uniform9(0u8..)) {
zebra_test::init();

// Only do the test if the bytes were valid.
if let Ok(s) = CompactSizeMessage::zcash_deserialize(Cursor::new(&bytes[..])) {
if let Ok(size) = CompactSizeMessage::zcash_deserialize(Cursor::new(&bytes[..])) {
// The CompactSize encoding is variable-length, so we may not even
// read all of the input bytes, and therefore we can't expect that
// the encoding will reproduce bytes that were never read. Instead,
// copy the input bytes, and overwrite them with the encoding of s,
// so that if the encoding is different, we'll catch it on the part
// that's written.
let mut expect_bytes = bytes;
s.zcash_serialize(Cursor::new(&mut expect_bytes[..])).unwrap();
size.zcash_serialize(Cursor::new(&mut expect_bytes[..])).unwrap();

prop_assert_eq!(bytes, expect_bytes);

// Also check the range is correct
let size: usize = size.into();
prop_assert!(size <= MAX_PROTOCOL_MESSAGE_LEN);
}
}

#[test]
fn compact_size_64_write_then_read_round_trip(s in any::<CompactSize64>()) {
fn compact_size_message_range(size in any::<usize>()) {
zebra_test::init();

let buf = s.zcash_serialize_to_vec().unwrap();
if let Ok(compact_size) = CompactSizeMessage::try_from(size) {
prop_assert!(size <= MAX_PROTOCOL_MESSAGE_LEN);

let compact_size: usize = compact_size.into();
prop_assert_eq!(size, compact_size);
} else {
prop_assert!(size > MAX_PROTOCOL_MESSAGE_LEN);
}
}

#[test]
fn compact_size_64_write_then_read_round_trip(size in any::<CompactSize64>()) {
zebra_test::init();

let buf = size.zcash_serialize_to_vec().unwrap();
// Maximum encoding size of a CompactSize is 9 bytes.
prop_assert!(buf.len() <= 9);

let expect_s: CompactSize64 = buf.zcash_deserialize_into().unwrap();
prop_assert_eq!(s, expect_s);
let expect_size: CompactSize64 = buf.zcash_deserialize_into().unwrap();
prop_assert_eq!(size, expect_size);
}

#[test]
Expand All @@ -74,6 +97,15 @@ proptest! {
}
}

#[test]
fn compact_size_64_conversion(size in any::<u64>()) {
zebra_test::init();

let compact_size = CompactSize64::from(size);
let compact_size: u64 = compact_size.into();
prop_assert_eq!(size, compact_size);
}

#[test]
fn transaction_serialized_size(transaction in any::<UnminedTx>()) {
zebra_test::init();
Expand Down

0 comments on commit dd01bb5

Please sign in to comment.