diff --git a/zebra-chain/Cargo.toml b/zebra-chain/Cargo.toml index 4e575cd0..767fc56f 100644 --- a/zebra-chain/Cargo.toml +++ b/zebra-chain/Cargo.toml @@ -20,3 +20,4 @@ ed25519-zebra = "0.1" [dev-dependencies] proptest = "0.9" +proptest-derive = "0.1.0" diff --git a/zebra-chain/proptest-regressions/types.txt b/zebra-chain/proptest-regressions/types.txt new file mode 100644 index 00000000..8d37aacf --- /dev/null +++ b/zebra-chain/proptest-regressions/types.txt @@ -0,0 +1,8 @@ +# 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 77e4c5adc662baed850ecd3142ba2d61fa50d7dc7f75e56a1cb4ac6307a9a7e2 # shrinks to locktime = Height(BlockHeight(0)) +cc dbb060756c70411d81f49af9c742cbea259314ddf03440ff00ef62770047e304 # shrinks to locktime = Time(2019-12-19T19:48:42.288928Z) diff --git a/zebra-chain/src/types.rs b/zebra-chain/src/types.rs index bf06981e..a355b982 100644 --- a/zebra-chain/src/types.rs +++ b/zebra-chain/src/types.rs @@ -8,6 +8,8 @@ use std::{ use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use chrono::{DateTime, TimeZone, Utc}; use hex; +#[cfg(test)] +use proptest_derive::Arbitrary; use crate::serialization::{ ReadZcashExt, SerializationError, WriteZcashExt, ZcashDeserialize, ZcashSerialize, @@ -124,3 +126,47 @@ mod tests { assert_eq!(format!("{:?}", checksum), "Sha256dChecksum(\"9595c9df\")"); } } + +#[cfg(test)] +mod proptest { + + use std::io::Cursor; + + use chrono::Utc; + use proptest::prelude::*; + + use super::{BlockHeight, LockTime}; + use crate::serialization::{ZcashDeserialize, ZcashSerialize}; + + impl Arbitrary for LockTime { + type Parameters = (); + + fn arbitrary_with(_args: ()) -> Self::Strategy { + prop_oneof![ + (0u32..500_000_000_u32).prop_map(|n| LockTime::Height(BlockHeight(n))), + Just(LockTime::Time(Utc::now())) + ] + .boxed() + } + + type Strategy = BoxedStrategy; + } + + proptest! { + + #[test] + fn locktime_roundtrip(locktime in any::()) { + let mut bytes = Cursor::new(Vec::new()); + locktime.zcash_serialize(&mut bytes)?; + + bytes.set_position(0); + let other_locktime = LockTime::zcash_deserialize(&mut bytes)?; + + prop_assert_eq![locktime, other_locktime]; + + + } + + + } +} diff --git a/zebra-network/src/protocol/external/types.rs b/zebra-network/src/protocol/external/types.rs index f836dae1..0839b8de 100644 --- a/zebra-network/src/protocol/external/types.rs +++ b/zebra-network/src/protocol/external/types.rs @@ -81,16 +81,6 @@ mod proptest { use super::Magic; - // impl Arbitrary for Magic { - // type Parameters = (); - - // fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { - // Magic - // } - - // type Strategy = BoxedStrategy; - // } - proptest! { #[test]