From 68a6837cc11cadce0f8cbb3111c938beebabd5da Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Tue, 19 Nov 2019 17:08:24 -0800 Subject: [PATCH] Add a bytes round-trip test for compactsize encoding. --- .../proptest-regressions/serialization.txt | 1 + zebra-chain/src/serialization.rs | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/zebra-chain/proptest-regressions/serialization.txt b/zebra-chain/proptest-regressions/serialization.txt index 1d0b6bee..f1f36db3 100644 --- a/zebra-chain/proptest-regressions/serialization.txt +++ b/zebra-chain/proptest-regressions/serialization.txt @@ -5,3 +5,4 @@ # It is recommended to check this file in to source control so that # everyone who runs the test benefits from these saved cases. cc ddefa5145f08994fb873af028344fc03d656dcd1f9287fac71dfa98cbd6a5090 # shrinks to s = 65536 +cc c04b21f87727bdd1fd9eb7a1616104fd65fa617f507bb6e8163be6542ff2ed68 # shrinks to bytes = [253, 0, 0, 0, 0, 0, 0, 0, 0] diff --git a/zebra-chain/src/serialization.rs b/zebra-chain/src/serialization.rs index da23c746..db12c463 100644 --- a/zebra-chain/src/serialization.rs +++ b/zebra-chain/src/serialization.rs @@ -282,16 +282,30 @@ mod tests { use std::io::Cursor; proptest! { - // The test below is cheap so we can run it a lot. + // The tests below are cheap so we can run them a lot. #![proptest_config(ProptestConfig::with_cases(100_000))] #[test] - fn compactsize_round_trip(s in 0u64..0x2_0000u64) { + fn compactsize_write_then_read_round_trip(s in 0u64..0x2_0000u64) { // Maximum encoding size of a compactsize is 9 bytes. let mut buf = [0u8; 8+1]; Cursor::new(&mut buf[..]).write_compactsize(s).unwrap(); let expect_s = Cursor::new(&buf[..]).read_compactsize().unwrap(); prop_assert_eq!(s, expect_s); } + + #[test] + fn compactsize_read_then_write_round_trip(bytes in prop::array::uniform9(0u8..)) { + let s = Cursor::new(&bytes[..]).read_compactsize().unwrap(); + // 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.clone(); + Cursor::new(&mut expect_bytes[..]).write_compactsize(s).unwrap(); + prop_assert_eq!(bytes, expect_bytes); + } } }