From ff8695de03f03ec7aed24fdb21bb78200f0a326b Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 25 May 2021 20:03:25 +0100 Subject: [PATCH] zcash_address: Add failing test showing unified::Address encoding bug --- .../proptest-regressions/kind/unified.txt | 7 +++ components/zcash_address/src/kind/unified.rs | 55 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 components/zcash_address/proptest-regressions/kind/unified.txt diff --git a/components/zcash_address/proptest-regressions/kind/unified.txt b/components/zcash_address/proptest-regressions/kind/unified.txt new file mode 100644 index 000000000..f70dff62c --- /dev/null +++ b/components/zcash_address/proptest-regressions/kind/unified.txt @@ -0,0 +1,7 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +cc e08469bc301313ef868b97a5c37d9a9746d9720c915a9127c89db25c3be778fd # shrinks to ua = Address([Sapling([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), P2pkh([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])]) diff --git a/components/zcash_address/src/kind/unified.rs b/components/zcash_address/src/kind/unified.rs index 3e028b34f..560208802 100644 --- a/components/zcash_address/src/kind/unified.rs +++ b/components/zcash_address/src/kind/unified.rs @@ -139,3 +139,58 @@ impl Address { .collect() } } + +#[cfg(test)] +mod tests { + use std::convert::TryFrom; + + use proptest::{ + array::{uniform11, uniform20, uniform32}, + prelude::*, + }; + + use super::{Address, Receiver}; + + prop_compose! { + fn uniform43()(a in uniform11(0u8..), b in uniform32(0u8..)) -> [u8; 43] { + let mut c = [0; 43]; + c[..11].copy_from_slice(&a); + c[11..].copy_from_slice(&b); + c + } + } + + fn arb_shielded_receiver() -> BoxedStrategy { + prop_oneof![ + uniform43().prop_map(Receiver::Sapling), + uniform43().prop_map(Receiver::Orchard), + ] + .boxed() + } + + fn arb_transparent_receiver() -> BoxedStrategy { + prop_oneof![ + uniform20(0u8..).prop_map(Receiver::P2pkh), + uniform20(0u8..).prop_map(Receiver::P2sh), + ] + .boxed() + } + + prop_compose! { + fn arb_unified_address()( + shielded in prop::collection::hash_set(arb_shielded_receiver(), 1..2), + transparent in prop::option::of(arb_transparent_receiver()), + ) -> Address { + Address(shielded.into_iter().chain(transparent).collect()) + } + } + + proptest! { + #[test] + fn ua_roundtrip(ua in arb_unified_address()) { + let bytes = ua.to_bytes(); + let decoded = Address::try_from(&bytes[..]); + prop_assert_eq!(decoded, Ok(ua)); + } + } +}