From 0b4e974c9e7b24591f97e04fc937e96862e144c6 Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Wed, 23 Sep 2020 18:52:52 -0700 Subject: [PATCH] export proptest impls for use in downstream crates (#1092) * export proptest impls for use in downstream crates * add testjob for disabled feature in zebra-chain * run rustfmt * try to fix github actions syntax * differentiate name * prove that github action tests zebra-chain build without features * revert change from last commit now that test is running * remove accidentally introduced newline * Update .github/workflows/ci.yml Co-authored-by: Deirdre Connolly Co-authored-by: Deirdre Connolly --- .github/workflows/ci.yml | 22 +++++++++++-- Cargo.lock | 1 + zebra-chain/Cargo.toml | 12 +++++-- zebra-chain/src/amount.rs | 31 ++++++++++--------- zebra-chain/src/block.rs | 6 ++-- .../src/block/{tests => }/arbitrary.rs | 2 +- zebra-chain/src/block/hash.rs | 4 +-- zebra-chain/src/block/height.rs | 4 +-- zebra-chain/src/block/merkle.rs | 4 +-- zebra-chain/src/block/tests.rs | 1 - zebra-chain/src/parameters/network.rs | 4 +-- zebra-chain/src/primitives/proofs/bctv14.rs | 4 +-- zebra-chain/src/primitives/proofs/groth16.rs | 4 +-- zebra-chain/src/sapling.rs | 2 ++ .../src/sapling/{tests => }/arbitrary.rs | 2 +- zebra-chain/src/sapling/commitment.rs | 2 +- zebra-chain/src/sapling/keys.rs | 8 ++--- zebra-chain/src/sapling/note.rs | 2 +- zebra-chain/src/sapling/note/ciphertexts.rs | 5 ++- zebra-chain/src/sapling/note/nullifiers.rs | 5 ++- zebra-chain/src/sapling/tests.rs | 2 +- zebra-chain/src/sapling/tree.rs | 6 ++-- zebra-chain/src/sprout.rs | 4 +-- .../src/sprout/{tests => }/arbitrary.rs | 2 +- zebra-chain/src/sprout/commitment.rs | 10 ++++-- zebra-chain/src/sprout/keys.rs | 13 +++++--- zebra-chain/src/sprout/note.rs | 7 +++-- zebra-chain/src/sprout/note/ciphertexts.rs | 5 ++- zebra-chain/src/sprout/note/mac.rs | 5 ++- zebra-chain/src/sprout/note/nullifiers.rs | 10 ++++-- zebra-chain/src/sprout/tree.rs | 4 +-- zebra-chain/src/transaction.rs | 2 ++ .../src/transaction/{tests => }/arbitrary.rs | 6 +++- zebra-chain/src/transaction/hash.rs | 4 +-- zebra-chain/src/transaction/tests.rs | 1 - zebra-chain/src/transparent.rs | 10 +++--- .../src/transparent/{tests => }/arbitrary.rs | 2 +- zebra-chain/src/transparent/script.rs | 5 ++- zebra-chain/src/transparent/tests.rs | 1 - zebra-chain/src/work.rs | 2 ++ zebra-chain/src/work/{tests => }/arbitrary.rs | 2 +- zebra-chain/src/work/difficulty.rs | 6 ++-- zebra-chain/src/work/tests.rs | 1 - zebra-state/Cargo.toml | 1 + zebra-test/Cargo.toml | 1 + zebra-test/src/prelude.rs | 1 + 46 files changed, 151 insertions(+), 87 deletions(-) rename zebra-chain/src/block/{tests => }/arbitrary.rs (98%) rename zebra-chain/src/sapling/{tests => }/arbitrary.rs (96%) rename zebra-chain/src/sprout/{tests => }/arbitrary.rs (96%) rename zebra-chain/src/transaction/{tests => }/arbitrary.rs (95%) rename zebra-chain/src/transparent/{tests => }/arbitrary.rs (94%) delete mode 100644 zebra-chain/src/transparent/tests.rs rename zebra-chain/src/work/{tests => }/arbitrary.rs (96%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9adedd26..7c1ec3aa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,7 +1,6 @@ name: CI - on: pull_request - + jobs: test: @@ -32,6 +31,25 @@ jobs: command: test args: --verbose --all + build-chain-no-features: + name: Build zebra-chain w/o features on ubuntu-latest + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + - name: cargo fetch + uses: actions-rs/cargo@v1 + with: + command: fetch + - name: Run build without features enabled + working-directory: ./zebra-chain + env: + RUST_BACKTRACE: full + run: cargo build --verbose --no-default-features + build: name: Build on ${{ matrix.os }} runs-on: ${{ matrix.os }} diff --git a/Cargo.lock b/Cargo.lock index a8543a42..b4f548b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3282,6 +3282,7 @@ dependencies = [ "lazy_static", "owo-colors", "pretty_assertions", + "proptest", "regex", "spandoc", "thiserror", diff --git a/zebra-chain/Cargo.toml b/zebra-chain/Cargo.toml index f02c0396..8fb60024 100644 --- a/zebra-chain/Cargo.toml +++ b/zebra-chain/Cargo.toml @@ -7,6 +7,11 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[features] + +default = [] +proptest-impl = ["proptest", "proptest-derive"] + [dependencies] bech32 = "0.7.2" bitvec = "0.17.4" @@ -29,6 +34,9 @@ sha2 = { version = "0.9.1", features=["compress"] } thiserror = "1" x25519-dalek = { version = "1.1", features = ["serde"] } +proptest = { version = "0.10", optional = true } +proptest-derive = { version = "0.2.0", optional = true } + # ZF deps displaydoc = "0.1.7" ed25519-zebra = "1" @@ -39,9 +47,9 @@ bitflags = "1.2.1" [dev-dependencies] bincode = "1" color-eyre = "0.5" -proptest = "0.10" -proptest-derive = "0.2.0" spandoc = "0.2" tracing = "0.1.19" +proptest = "0.10" +proptest-derive = "0.2" zebra-test = { path = "../zebra-test/" } diff --git a/zebra-chain/src/amount.rs b/zebra-chain/src/amount.rs index 9f4d74ac..17b0633b 100644 --- a/zebra-chain/src/amount.rs +++ b/zebra-chain/src/amount.rs @@ -296,25 +296,26 @@ impl ZcashDeserialize for Amount { } } +#[cfg(any(test, feature = "proptest-impl"))] +use proptest::prelude::*; +#[cfg(any(test, feature = "proptest-impl"))] +impl Arbitrary for Amount +where + C: Constraint + std::fmt::Debug, +{ + type Parameters = (); + + fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { + C::valid_range().prop_map(|v| Self(v, PhantomData)).boxed() + } + + type Strategy = BoxedStrategy; +} + #[cfg(test)] mod test { use super::*; use color_eyre::eyre::Result; - use proptest::prelude::*; - use std::fmt; - - impl Arbitrary for Amount - where - C: Constraint + fmt::Debug, - { - type Parameters = (); - - fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { - C::valid_range().prop_map(|v| Self(v, PhantomData)).boxed() - } - - type Strategy = BoxedStrategy; - } #[test] fn test_add_bare() -> Result<()> { diff --git a/zebra-chain/src/block.rs b/zebra-chain/src/block.rs index 9215a484..ac4df10a 100644 --- a/zebra-chain/src/block.rs +++ b/zebra-chain/src/block.rs @@ -9,6 +9,8 @@ mod serialize; pub mod merkle; +#[cfg(any(test, feature = "proptest-impl"))] +mod arbitrary; #[cfg(test)] mod tests; @@ -25,12 +27,12 @@ use serde::{Deserialize, Serialize}; use crate::{parameters::Network, transaction::Transaction, transparent}; -#[cfg(test)] +#[cfg(any(test, feature = "proptest-impl"))] use proptest_derive::Arbitrary; /// A Zcash block, containing a header and a list of transactions. #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -#[cfg_attr(test, derive(Arbitrary))] +#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))] pub struct Block { /// The block header, containing block metadata. pub header: Header, diff --git a/zebra-chain/src/block/tests/arbitrary.rs b/zebra-chain/src/block/arbitrary.rs similarity index 98% rename from zebra-chain/src/block/tests/arbitrary.rs rename to zebra-chain/src/block/arbitrary.rs index 068362a3..63b62215 100644 --- a/zebra-chain/src/block/tests/arbitrary.rs +++ b/zebra-chain/src/block/arbitrary.rs @@ -1,7 +1,7 @@ use crate::parameters::Network; use crate::work::{difficulty::CompactDifficulty, equihash}; -use super::super::*; +use super::*; use chrono::{TimeZone, Utc}; use proptest::{ diff --git a/zebra-chain/src/block/hash.rs b/zebra-chain/src/block/hash.rs index 7a6ed861..cbe12353 100644 --- a/zebra-chain/src/block/hash.rs +++ b/zebra-chain/src/block/hash.rs @@ -1,6 +1,6 @@ use std::{fmt, io}; -#[cfg(test)] +#[cfg(any(test, feature = "proptest-impl"))] use proptest_derive::Arbitrary; use serde::{Deserialize, Serialize}; @@ -19,7 +19,7 @@ use super::Header; /// Note: Zebra displays transaction and block hashes in their actual byte-order, /// not in reversed byte-order. #[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] -#[cfg_attr(test, derive(Arbitrary))] +#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))] pub struct Hash(pub [u8; 32]); impl fmt::Display for Hash { diff --git a/zebra-chain/src/block/height.rs b/zebra-chain/src/block/height.rs index d66c670e..d10afce1 100644 --- a/zebra-chain/src/block/height.rs +++ b/zebra-chain/src/block/height.rs @@ -79,9 +79,9 @@ impl Sub for Height { } } -#[cfg(test)] +#[cfg(any(test, feature = "proptest-impl"))] use proptest::prelude::*; -#[cfg(test)] +#[cfg(any(test, feature = "proptest-impl"))] impl Arbitrary for Height { type Parameters = (); diff --git a/zebra-chain/src/block/merkle.rs b/zebra-chain/src/block/merkle.rs index 8bd4e9fe..61fbe3af 100644 --- a/zebra-chain/src/block/merkle.rs +++ b/zebra-chain/src/block/merkle.rs @@ -3,7 +3,7 @@ use std::{fmt, io}; -#[cfg(test)] +#[cfg(any(any(test, feature = "proptest-impl"), feature = "proptest-impl"))] use proptest_derive::Arbitrary; use crate::serialization::{sha256d, SerializationError, ZcashDeserialize, ZcashSerialize}; @@ -31,7 +31,7 @@ impl ZcashDeserialize for Tree { /// A SHA-256d hash of the root node of a merkle tree of SHA256-d /// hashed transactions in a block. #[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize)] -#[cfg_attr(test, derive(Arbitrary))] +#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))] pub struct Root(pub [u8; 32]); impl From> for Root { diff --git a/zebra-chain/src/block/tests.rs b/zebra-chain/src/block/tests.rs index a0d3e4ff..a63253a6 100644 --- a/zebra-chain/src/block/tests.rs +++ b/zebra-chain/src/block/tests.rs @@ -1,4 +1,3 @@ -mod arbitrary; // XXX this should be rewritten as strategies mod generate; mod prop; diff --git a/zebra-chain/src/parameters/network.rs b/zebra-chain/src/parameters/network.rs index d82c010b..bbf78e83 100644 --- a/zebra-chain/src/parameters/network.rs +++ b/zebra-chain/src/parameters/network.rs @@ -1,9 +1,9 @@ -#[cfg(test)] +#[cfg(any(test, feature = "proptest-impl"))] use proptest_derive::Arbitrary; /// An enum describing the possible network choices. #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)] -#[cfg_attr(test, derive(Arbitrary))] +#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))] pub enum Network { /// The production mainnet. Mainnet, diff --git a/zebra-chain/src/primitives/proofs/bctv14.rs b/zebra-chain/src/primitives/proofs/bctv14.rs index 638d6686..8fd22da0 100644 --- a/zebra-chain/src/primitives/proofs/bctv14.rs +++ b/zebra-chain/src/primitives/proofs/bctv14.rs @@ -51,10 +51,10 @@ impl ZcashDeserialize for Bctv14Proof { } } -#[cfg(test)] +#[cfg(any(test, feature = "proptest-impl"))] use proptest::{arbitrary::Arbitrary, collection::vec, prelude::*}; -#[cfg(test)] +#[cfg(any(test, feature = "proptest-impl"))] impl Arbitrary for Bctv14Proof { type Parameters = (); diff --git a/zebra-chain/src/primitives/proofs/groth16.rs b/zebra-chain/src/primitives/proofs/groth16.rs index a1c13072..41494bbc 100644 --- a/zebra-chain/src/primitives/proofs/groth16.rs +++ b/zebra-chain/src/primitives/proofs/groth16.rs @@ -50,10 +50,10 @@ impl ZcashDeserialize for Groth16Proof { } } -#[cfg(test)] +#[cfg(any(test, feature = "proptest-impl"))] use proptest::{arbitrary::Arbitrary, collection::vec, prelude::*}; -#[cfg(test)] +#[cfg(any(test, feature = "proptest-impl"))] impl Arbitrary for Groth16Proof { type Parameters = (); diff --git a/zebra-chain/src/sapling.rs b/zebra-chain/src/sapling.rs index a1f59404..5f491a2f 100644 --- a/zebra-chain/src/sapling.rs +++ b/zebra-chain/src/sapling.rs @@ -1,6 +1,8 @@ //! Sapling-related functionality. mod address; +#[cfg(any(test, feature = "proptest-impl"))] +mod arbitrary; mod commitment; mod note; mod output; diff --git a/zebra-chain/src/sapling/tests/arbitrary.rs b/zebra-chain/src/sapling/arbitrary.rs similarity index 96% rename from zebra-chain/src/sapling/tests/arbitrary.rs rename to zebra-chain/src/sapling/arbitrary.rs index a0b485e7..a9b6885f 100644 --- a/zebra-chain/src/sapling/tests/arbitrary.rs +++ b/zebra-chain/src/sapling/arbitrary.rs @@ -2,7 +2,7 @@ use proptest::{arbitrary::any, array, collection::vec, prelude::*}; use crate::primitives::Groth16Proof; -use super::super::{commitment, keys, note, tree, Output, Spend}; +use super::{commitment, keys, note, tree, Output, Spend}; impl Arbitrary for Spend { type Parameters = (); diff --git a/zebra-chain/src/sapling/commitment.rs b/zebra-chain/src/sapling/commitment.rs index 81ab05d9..ad3b019c 100644 --- a/zebra-chain/src/sapling/commitment.rs +++ b/zebra-chain/src/sapling/commitment.rs @@ -1,6 +1,6 @@ //! Note and value commitments. -#[cfg(test)] +#[cfg(any(test, feature = "proptest-impl"))] mod arbitrary; #[cfg(test)] mod test_vectors; diff --git a/zebra-chain/src/sapling/keys.rs b/zebra-chain/src/sapling/keys.rs index 064420b1..9b6f019d 100644 --- a/zebra-chain/src/sapling/keys.rs +++ b/zebra-chain/src/sapling/keys.rs @@ -9,7 +9,7 @@ //! [3.1]: https://zips.z.cash/protocol/protocol.pdf#addressesandkeys #![allow(clippy::unit_arg)] -#[cfg(test)] +#[cfg(any(test, feature = "proptest-impl"))] mod arbitrary; #[cfg(test)] mod test_vectors; @@ -26,7 +26,7 @@ use std::{ use bech32::{self, FromBase32, ToBase32}; use rand_core::{CryptoRng, RngCore}; -#[cfg(test)] +#[cfg(any(test, feature = "proptest-impl"))] use proptest_derive::Arbitrary; use crate::{ @@ -183,7 +183,7 @@ mod sk_hrp { /// /// [ps]: https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents #[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[cfg_attr(test, derive(Arbitrary))] +#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))] pub struct SpendingKey { network: Network, bytes: [u8; 32], @@ -610,7 +610,7 @@ impl PartialEq<[u8; 32]> for IncomingViewingKey { /// /// [ps]: https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents #[derive(Copy, Clone, Eq, PartialEq)] -#[cfg_attr(test, derive(Arbitrary))] +#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))] pub struct Diversifier(pub [u8; 11]); impl fmt::Debug for Diversifier { diff --git a/zebra-chain/src/sapling/note.rs b/zebra-chain/src/sapling/note.rs index 5425cf48..40de64b1 100644 --- a/zebra-chain/src/sapling/note.rs +++ b/zebra-chain/src/sapling/note.rs @@ -6,7 +6,7 @@ mod ciphertexts; mod nullifiers; -#[cfg(test)] +#[cfg(any(test, feature = "proptest-impl"))] mod arbitrary; use crate::{ diff --git a/zebra-chain/src/sapling/note/ciphertexts.rs b/zebra-chain/src/sapling/note/ciphertexts.rs index 4f5fe24e..f5215d18 100644 --- a/zebra-chain/src/sapling/note/ciphertexts.rs +++ b/zebra-chain/src/sapling/note/ciphertexts.rs @@ -1,8 +1,5 @@ use std::{fmt, io}; -#[cfg(test)] -use proptest::{arbitrary::any, prelude::*}; - use crate::serialization::{serde_helpers, SerializationError, ZcashDeserialize, ZcashSerialize}; /// A ciphertext component for encrypted output notes. @@ -103,6 +100,8 @@ impl ZcashDeserialize for WrappedNoteKey { } } +#[cfg(test)] +use proptest::prelude::*; #[cfg(test)] proptest! { diff --git a/zebra-chain/src/sapling/note/nullifiers.rs b/zebra-chain/src/sapling/note/nullifiers.rs index db3661c2..98a49706 100644 --- a/zebra-chain/src/sapling/note/nullifiers.rs +++ b/zebra-chain/src/sapling/note/nullifiers.rs @@ -27,7 +27,10 @@ fn prf_nf(nk: [u8; 32], rho: [u8; 32]) -> [u8; 32] { /// A Nullifier for Sapling transactions #[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)] -#[cfg_attr(test, derive(proptest_derive::Arbitrary))] +#[cfg_attr( + any(test, feature = "proptest-impl"), + derive(proptest_derive::Arbitrary) +)] pub struct Nullifier([u8; 32]); impl From<[u8; 32]> for Nullifier { diff --git a/zebra-chain/src/sapling/tests.rs b/zebra-chain/src/sapling/tests.rs index be9770e9..8b137891 100644 --- a/zebra-chain/src/sapling/tests.rs +++ b/zebra-chain/src/sapling/tests.rs @@ -1 +1 @@ -mod arbitrary; + diff --git a/zebra-chain/src/sapling/tree.rs b/zebra-chain/src/sapling/tree.rs index a111c3ac..8fa44cbd 100644 --- a/zebra-chain/src/sapling/tree.rs +++ b/zebra-chain/src/sapling/tree.rs @@ -16,7 +16,7 @@ use std::{fmt, io}; use bitvec::prelude::*; -#[cfg(test)] +#[cfg(any(test, feature = "proptest-impl"))] use proptest_derive::Arbitrary; use crate::serialization::{SerializationError, ZcashDeserialize, ZcashSerialize}; @@ -53,7 +53,7 @@ pub struct Position(pub(crate) u64); /// Sapling Note Commitment Tree #[derive(Clone, Debug, Default, Eq, PartialEq)] -#[cfg_attr(test, derive(Arbitrary))] +#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))] struct SaplingNoteCommitmentTree; /// Sapling note commitment tree root node hash. @@ -63,7 +63,7 @@ struct SaplingNoteCommitmentTree; /// this block. A root of a note commitment tree is associated with /// each treestate. #[derive(Clone, Copy, Default, Eq, PartialEq, Serialize, Deserialize)] -#[cfg_attr(test, derive(Arbitrary))] +#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))] pub struct Root(pub [u8; 32]); impl fmt::Debug for Root { diff --git a/zebra-chain/src/sprout.rs b/zebra-chain/src/sprout.rs index ef4941fa..919777aa 100644 --- a/zebra-chain/src/sprout.rs +++ b/zebra-chain/src/sprout.rs @@ -1,8 +1,8 @@ //! Sprout-related functionality. +#[cfg(any(test, feature = "proptest-impl"))] +mod arbitrary; mod joinsplit; -#[cfg(test)] -mod tests; // XXX clean up these modules diff --git a/zebra-chain/src/sprout/tests/arbitrary.rs b/zebra-chain/src/sprout/arbitrary.rs similarity index 96% rename from zebra-chain/src/sprout/tests/arbitrary.rs rename to zebra-chain/src/sprout/arbitrary.rs index c1aac700..623b491d 100644 --- a/zebra-chain/src/sprout/tests/arbitrary.rs +++ b/zebra-chain/src/sprout/arbitrary.rs @@ -5,7 +5,7 @@ use crate::{ primitives::ZkSnarkProof, }; -use super::super::{commitment, note, tree, JoinSplit}; +use super::{commitment, note, tree, JoinSplit}; impl Arbitrary for JoinSplit

{ type Parameters = (); diff --git a/zebra-chain/src/sprout/commitment.rs b/zebra-chain/src/sprout/commitment.rs index 379f67a3..f47e4665 100644 --- a/zebra-chain/src/sprout/commitment.rs +++ b/zebra-chain/src/sprout/commitment.rs @@ -8,7 +8,10 @@ use super::note::Note; /// The randomness used in the Pedersen Hash for note commitment. #[derive(Copy, Clone, Debug, PartialEq)] -#[cfg_attr(test, derive(proptest_derive::Arbitrary))] +#[cfg_attr( + any(test, feature = "proptest-impl"), + derive(proptest_derive::Arbitrary) +)] pub struct CommitmentRandomness(pub [u8; 32]); impl AsRef<[u8]> for CommitmentRandomness { @@ -19,7 +22,10 @@ impl AsRef<[u8]> for CommitmentRandomness { /// Note commitments for the output notes. #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] -#[cfg_attr(test, derive(proptest_derive::Arbitrary))] +#[cfg_attr( + any(test, feature = "proptest-impl"), + derive(proptest_derive::Arbitrary) +)] pub struct NoteCommitment(pub(crate) [u8; 32]); impl Eq for NoteCommitment {} diff --git a/zebra-chain/src/sprout/keys.rs b/zebra-chain/src/sprout/keys.rs index cc96a260..e9c562a0 100644 --- a/zebra-chain/src/sprout/keys.rs +++ b/zebra-chain/src/sprout/keys.rs @@ -13,9 +13,9 @@ use byteorder::{ByteOrder, LittleEndian}; use rand_core::{CryptoRng, RngCore}; use sha2::digest::generic_array::{typenum::U64, GenericArray}; -#[cfg(test)] +#[cfg(any(test, feature = "proptest-impl"))] use proptest::{array, prelude::*}; -#[cfg(test)] +#[cfg(any(test, feature = "proptest-impl"))] use proptest_derive::Arbitrary; use crate::{ @@ -61,7 +61,7 @@ fn prf_addr(x: [u8; 32], t: u8) -> [u8; 32] { /// All other Sprout key types derive from the SpendingKey value. /// Actually 252 bits. #[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[cfg_attr(test, derive(Arbitrary))] +#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))] pub struct SpendingKey { /// What would normally be the value inside a tuple struct. pub bytes: [u8; 32], @@ -183,7 +183,10 @@ impl From for ReceivingKey { /// Derived from a _SpendingKey_. #[derive(Copy, Clone, Eq, PartialEq)] -#[cfg_attr(test, derive(proptest_derive::Arbitrary))] +#[cfg_attr( + any(test, feature = "proptest-impl"), + derive(proptest_derive::Arbitrary) +)] pub struct PayingKey(pub [u8; 32]); impl AsRef<[u8]> for PayingKey { @@ -310,7 +313,7 @@ impl std::str::FromStr for IncomingViewingKey { } } -#[cfg(test)] +#[cfg(any(test, feature = "proptest-impl"))] impl Arbitrary for IncomingViewingKey { type Parameters = (); diff --git a/zebra-chain/src/sprout/note.rs b/zebra-chain/src/sprout/note.rs index 860da6c2..305add8f 100644 --- a/zebra-chain/src/sprout/note.rs +++ b/zebra-chain/src/sprout/note.rs @@ -3,7 +3,7 @@ #![allow(clippy::unit_arg)] #![allow(dead_code)] -#[cfg(test)] +#[cfg(any(test, feature = "proptest-impl"))] mod arbitrary; mod ciphertexts; mod mac; @@ -28,7 +28,10 @@ pub use nullifiers::{Nullifier, NullifierSeed}; /// /// https://zips.z.cash/protocol/protocol.pdf#notes #[derive(Clone, Debug)] -#[cfg_attr(test, derive(proptest_derive::Arbitrary))] +#[cfg_attr( + any(test, feature = "proptest-impl"), + derive(proptest_derive::Arbitrary) +)] pub struct Note { /// The paying key of the recipient’s shielded payment address pub paying_key: PayingKey, diff --git a/zebra-chain/src/sprout/note/ciphertexts.rs b/zebra-chain/src/sprout/note/ciphertexts.rs index 032c8202..51535510 100644 --- a/zebra-chain/src/sprout/note/ciphertexts.rs +++ b/zebra-chain/src/sprout/note/ciphertexts.rs @@ -1,8 +1,5 @@ use std::{fmt, io}; -#[cfg(test)] -use proptest::{arbitrary::any, prelude::*}; - use serde::{Deserialize, Serialize}; use crate::serialization::{serde_helpers, SerializationError, ZcashDeserialize, ZcashSerialize}; @@ -56,6 +53,8 @@ impl ZcashDeserialize for EncryptedNote { } } +#[cfg(test)] +use proptest::prelude::*; #[cfg(test)] proptest! { diff --git a/zebra-chain/src/sprout/note/mac.rs b/zebra-chain/src/sprout/note/mac.rs index 4c5bc3c9..845f885b 100644 --- a/zebra-chain/src/sprout/note/mac.rs +++ b/zebra-chain/src/sprout/note/mac.rs @@ -6,7 +6,10 @@ use std::io::{self, Read}; /// binding h_sig to each a_sk of the JoinSplit description, computed as /// described in § 4.10 ‘Non-malleability (Sprout)’ on p. 37 #[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize)] -#[cfg_attr(test, derive(proptest_derive::Arbitrary))] +#[cfg_attr( + any(test, feature = "proptest-impl"), + derive(proptest_derive::Arbitrary) +)] pub struct MAC([u8; 32]); impl ZcashDeserialize for MAC { diff --git a/zebra-chain/src/sprout/note/nullifiers.rs b/zebra-chain/src/sprout/note/nullifiers.rs index 8513739f..19fa3299 100644 --- a/zebra-chain/src/sprout/note/nullifiers.rs +++ b/zebra-chain/src/sprout/note/nullifiers.rs @@ -37,7 +37,10 @@ fn prf_nf(a_sk: [u8; 32], rho: [u8; 32]) -> [u8; 32] { /// [ps]: https://zips.z.cash/protocol/protocol.pdf#sproutkeycomponents #[derive(Clone, Copy, Debug)] -#[cfg_attr(test, derive(proptest_derive::Arbitrary))] +#[cfg_attr( + any(test, feature = "proptest-impl"), + derive(proptest_derive::Arbitrary) +)] pub struct NullifierSeed(pub(crate) [u8; 32]); impl AsRef<[u8]> for NullifierSeed { @@ -60,7 +63,10 @@ impl From for [u8; 32] { /// A Nullifier for Sprout transactions #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[cfg_attr(test, derive(proptest_derive::Arbitrary))] +#[cfg_attr( + any(test, feature = "proptest-impl"), + derive(proptest_derive::Arbitrary) +)] pub struct Nullifier(pub(crate) [u8; 32]); impl From<[u8; 32]> for Nullifier { diff --git a/zebra-chain/src/sprout/tree.rs b/zebra-chain/src/sprout/tree.rs index 58e9b23c..9cccd7e2 100644 --- a/zebra-chain/src/sprout/tree.rs +++ b/zebra-chain/src/sprout/tree.rs @@ -13,7 +13,7 @@ use std::fmt; -#[cfg(test)] +#[cfg(any(test, feature = "proptest-impl"))] use proptest_derive::Arbitrary; /// Sprout note commitment tree root node hash. @@ -23,7 +23,7 @@ use proptest_derive::Arbitrary; /// this block. A root of a note commitment tree is associated with /// each treestate. #[derive(Clone, Copy, Default, Eq, PartialEq, Serialize, Deserialize)] -#[cfg_attr(test, derive(Arbitrary))] +#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))] pub struct Root([u8; 32]); impl fmt::Debug for Root { diff --git a/zebra-chain/src/transaction.rs b/zebra-chain/src/transaction.rs index f814893d..6e10aedc 100644 --- a/zebra-chain/src/transaction.rs +++ b/zebra-chain/src/transaction.rs @@ -10,6 +10,8 @@ mod serialize; mod shielded_data; mod sighash; +#[cfg(any(test, feature = "proptest-impl"))] +mod arbitrary; #[cfg(test)] mod tests; diff --git a/zebra-chain/src/transaction/tests/arbitrary.rs b/zebra-chain/src/transaction/arbitrary.rs similarity index 95% rename from zebra-chain/src/transaction/tests/arbitrary.rs rename to zebra-chain/src/transaction/arbitrary.rs index 6660fec2..f85776c1 100644 --- a/zebra-chain/src/transaction/tests/arbitrary.rs +++ b/zebra-chain/src/transaction/arbitrary.rs @@ -9,9 +9,10 @@ use crate::{ sapling, sprout, transparent, }; -use super::super::{JoinSplitData, LockTime, Memo, ShieldedData, Transaction}; +use super::{JoinSplitData, LockTime, Memo, ShieldedData, Transaction}; impl Transaction { + /// Generate a proptest strategy for V1 Transactions pub fn v1_strategy() -> impl Strategy { ( vec(any::(), 0..10), @@ -26,6 +27,7 @@ impl Transaction { .boxed() } + /// Generate a proptest strategy for V2 Transactions pub fn v2_strategy() -> impl Strategy { ( vec(any::(), 0..10), @@ -44,6 +46,7 @@ impl Transaction { .boxed() } + /// Generate a proptest strategy for V3 Transactions pub fn v3_strategy() -> impl Strategy { ( vec(any::(), 0..10), @@ -64,6 +67,7 @@ impl Transaction { .boxed() } + /// Generate a proptest strategy for V4 Transactions pub fn v4_strategy() -> impl Strategy { ( vec(any::(), 0..10), diff --git a/zebra-chain/src/transaction/hash.rs b/zebra-chain/src/transaction/hash.rs index cc526b35..63358258 100644 --- a/zebra-chain/src/transaction/hash.rs +++ b/zebra-chain/src/transaction/hash.rs @@ -1,7 +1,7 @@ #![allow(clippy::unit_arg)] use std::fmt; -#[cfg(test)] +#[cfg(any(test, feature = "proptest-impl"))] use proptest_derive::Arbitrary; use serde::{Deserialize, Serialize}; @@ -14,7 +14,7 @@ use super::Transaction; /// Note: Zebra displays transaction and block hashes in their actual byte-order, /// not in reversed byte-order. #[derive(Copy, Clone, Eq, PartialEq, Serialize, Deserialize, Hash)] -#[cfg_attr(test, derive(Arbitrary))] +#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))] pub struct Hash(pub [u8; 32]); impl<'a> From<&'a Transaction> for Hash { diff --git a/zebra-chain/src/transaction/tests.rs b/zebra-chain/src/transaction/tests.rs index 263a67a8..cc95d9d4 100644 --- a/zebra-chain/src/transaction/tests.rs +++ b/zebra-chain/src/transaction/tests.rs @@ -1,3 +1,2 @@ -mod arbitrary; mod prop; mod vectors; diff --git a/zebra-chain/src/transparent.rs b/zebra-chain/src/transparent.rs index a8713632..d2f9e6c6 100644 --- a/zebra-chain/src/transparent.rs +++ b/zebra-chain/src/transparent.rs @@ -9,9 +9,9 @@ mod serialize; pub use address::Address; pub use script::Script; -#[cfg(test)] -mod tests; -#[cfg(test)] +#[cfg(any(test, feature = "proptest-impl"))] +mod arbitrary; +#[cfg(any(test, feature = "proptest-impl"))] use proptest_derive::Arbitrary; use crate::{ @@ -41,7 +41,7 @@ impl AsRef<[u8]> for CoinbaseData { /// /// A particular transaction output reference. #[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -#[cfg_attr(test, derive(Arbitrary))] +#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))] pub struct OutPoint { /// References the transaction that contains the UTXO being spent. pub hash: transaction::Hash, @@ -87,7 +87,7 @@ pub enum Input { /// that spends my UTXO and sends 1 ZEC to you and 1 ZEC back to me /// (just like receiving change). #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -#[cfg_attr(test, derive(Arbitrary))] +#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))] pub struct Output { /// Transaction value. // At https://en.bitcoin.it/wiki/Protocol_documentation#tx, this is an i64. diff --git a/zebra-chain/src/transparent/tests/arbitrary.rs b/zebra-chain/src/transparent/arbitrary.rs similarity index 94% rename from zebra-chain/src/transparent/tests/arbitrary.rs rename to zebra-chain/src/transparent/arbitrary.rs index 7535baec..d8018e2a 100644 --- a/zebra-chain/src/transparent/tests/arbitrary.rs +++ b/zebra-chain/src/transparent/arbitrary.rs @@ -2,7 +2,7 @@ use proptest::{arbitrary::any, collection::vec, prelude::*}; use crate::block; -use super::super::{CoinbaseData, Input, OutPoint, Script}; +use super::{CoinbaseData, Input, OutPoint, Script}; impl Arbitrary for Input { type Parameters = (); diff --git a/zebra-chain/src/transparent/script.rs b/zebra-chain/src/transparent/script.rs index 75d09e5f..9f9572ef 100644 --- a/zebra-chain/src/transparent/script.rs +++ b/zebra-chain/src/transparent/script.rs @@ -9,7 +9,10 @@ use std::{ /// An encoding of a Bitcoin script. #[derive(Clone, Eq, PartialEq, Serialize, Deserialize)] -#[cfg_attr(test, derive(proptest_derive::Arbitrary))] +#[cfg_attr( + any(test, feature = "proptest-impl"), + derive(proptest_derive::Arbitrary) +)] pub struct Script(pub Vec); impl fmt::Debug for Script { diff --git a/zebra-chain/src/transparent/tests.rs b/zebra-chain/src/transparent/tests.rs deleted file mode 100644 index be9770e9..00000000 --- a/zebra-chain/src/transparent/tests.rs +++ /dev/null @@ -1 +0,0 @@ -mod arbitrary; diff --git a/zebra-chain/src/work.rs b/zebra-chain/src/work.rs index 35e87c17..25b0dd49 100644 --- a/zebra-chain/src/work.rs +++ b/zebra-chain/src/work.rs @@ -3,5 +3,7 @@ pub mod difficulty; pub mod equihash; +#[cfg(any(test, feature = "proptest-impl"))] +mod arbitrary; #[cfg(test)] mod tests; diff --git a/zebra-chain/src/work/tests/arbitrary.rs b/zebra-chain/src/work/arbitrary.rs similarity index 96% rename from zebra-chain/src/work/tests/arbitrary.rs rename to zebra-chain/src/work/arbitrary.rs index 0332ee71..a1a03468 100644 --- a/zebra-chain/src/work/tests/arbitrary.rs +++ b/zebra-chain/src/work/arbitrary.rs @@ -1,4 +1,4 @@ -use super::super::*; +use super::*; use proptest::{arbitrary::Arbitrary, collection::vec, prelude::*}; diff --git a/zebra-chain/src/work/difficulty.rs b/zebra-chain/src/work/difficulty.rs index 7802d02d..80ecfa11 100644 --- a/zebra-chain/src/work/difficulty.rs +++ b/zebra-chain/src/work/difficulty.rs @@ -18,9 +18,9 @@ use std::{fmt, ops::Add, ops::AddAssign}; use primitive_types::U256; -#[cfg(test)] +#[cfg(any(test, feature = "proptest-impl"))] use proptest_derive::Arbitrary; -#[cfg(test)] +#[cfg(tests)] mod tests; /// A 32-bit "compact bits" value, which represents the difficulty threshold for @@ -52,7 +52,7 @@ mod tests; /// multiple equivalent `CompactDifficulty` values, due to redundancy in the /// floating-point format. #[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize)] -#[cfg_attr(test, derive(Arbitrary))] +#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))] pub struct CompactDifficulty(pub u32); impl fmt::Debug for CompactDifficulty { diff --git a/zebra-chain/src/work/tests.rs b/zebra-chain/src/work/tests.rs index 263a67a8..cc95d9d4 100644 --- a/zebra-chain/src/work/tests.rs +++ b/zebra-chain/src/work/tests.rs @@ -1,3 +1,2 @@ -mod arbitrary; mod prop; mod vectors; diff --git a/zebra-state/Cargo.toml b/zebra-state/Cargo.toml index 72887ef5..3162c70c 100644 --- a/zebra-state/Cargo.toml +++ b/zebra-state/Cargo.toml @@ -26,6 +26,7 @@ thiserror = "1.0.20" tokio = { version = "0.2.22", features = ["sync"] } [dev-dependencies] +zebra-chain = { path = "../zebra-chain", features = ["proptest-impl"] } zebra-test = { path = "../zebra-test/" } once_cell = "1.4" diff --git a/zebra-test/Cargo.toml b/zebra-test/Cargo.toml index 35d83fda..9318da19 100644 --- a/zebra-test/Cargo.toml +++ b/zebra-test/Cargo.toml @@ -21,6 +21,7 @@ regex = "1.3.9" thiserror = "1.0.20" pretty_assertions = "0.6.1" owo-colors = "1.1.3" +proptest = "0.10.1" [dev-dependencies] tokio = { version = "0.2", features = ["full"] } diff --git a/zebra-test/src/prelude.rs b/zebra-test/src/prelude.rs index 7201bca8..c603683f 100644 --- a/zebra-test/src/prelude.rs +++ b/zebra-test/src/prelude.rs @@ -5,3 +5,4 @@ pub use color_eyre; pub use color_eyre::eyre; pub use eyre::Result; pub use pretty_assertions::{assert_eq, assert_ne}; +pub use proptest::prelude::*;