1use super::*;
23use proptest::{collection::vec, prelude::*};
45impl Arbitrary for CompactDifficulty {
6type Parameters = ();
78fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
9 (vec(any::<u8>(), 32))
10 .prop_filter_map("zero CompactDifficulty values are invalid", |v| {
11let mut bytes = [0; 32];
12 bytes.copy_from_slice(v.as_slice());
13if bytes == [0; 32] {
14return None;
15 }
16// In the Zcash protocol, a CompactDifficulty is generated using the difficulty
17 // adjustment functions. Instead of using those functions, we make a random
18 // ExpandedDifficulty, then convert it to a CompactDifficulty.
19Some(ExpandedDifficulty::from_hash(&block::Hash(bytes)).to_compact())
20 })
21 .boxed()
22 }
2324type Strategy = BoxedStrategy<Self>;
25}
2627impl Arbitrary for ExpandedDifficulty {
28type Parameters = ();
2930fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
31 any::<CompactDifficulty>()
32 .prop_map(|d| {
33// In the Zcash protocol, an ExpandedDifficulty is converted from a CompactDifficulty,
34 // or generated using the difficulty adjustment functions. We use the conversion in
35 // our proptest strategy.
36d.to_expanded()
37 .expect("arbitrary CompactDifficulty is valid")
38 })
39 .boxed()
40 }
4142type Strategy = BoxedStrategy<Self>;
43}
4445impl Arbitrary for Work {
46type Parameters = ();
4748fn arbitrary_with(_args: ()) -> Self::Strategy {
49// In the Zcash protocol, a Work is converted from an ExpandedDifficulty.
50 // But some randomised difficulties are impractically large, and will
51 // never appear in any real-world block. So we just use a random Work value.
52(1..u128::MAX).prop_map(Work).boxed()
53 }
5455type Strategy = BoxedStrategy<Self>;
56}
5758impl Arbitrary for PartialCumulativeWork {
59type Parameters = ();
6061fn arbitrary_with(_args: ()) -> Self::Strategy {
62// In Zebra's implementation, a PartialCumulativeWork is the sum of 0..100 Work values.
63 // But our Work values are randomised, rather than being derived from real-world
64 // difficulties. So we don't need to sum multiple Work values here.
65(any::<Work>())
66 .prop_map(PartialCumulativeWork::from)
67 .boxed()
68 }
6970type Strategy = BoxedStrategy<Self>;
71}