145 lines
4.1 KiB
Rust
145 lines
4.1 KiB
Rust
use proptest::{
|
|
arbitrary::{any, Arbitrary},
|
|
collection::vec,
|
|
option,
|
|
prelude::*,
|
|
};
|
|
|
|
use crate::{
|
|
serialization::{ZcashDeserialize, ZcashSerialize},
|
|
types::LockTime,
|
|
};
|
|
|
|
use super::*;
|
|
|
|
#[cfg(test)]
|
|
impl Transaction {
|
|
pub fn v1_strategy() -> impl Strategy<Value = Self> {
|
|
(
|
|
vec(any::<TransparentInput>(), 0..10),
|
|
vec(any::<TransparentOutput>(), 0..10),
|
|
any::<LockTime>(),
|
|
)
|
|
.prop_map(|(inputs, outputs, lock_time)| Transaction::V1 {
|
|
inputs: inputs,
|
|
outputs: outputs,
|
|
lock_time: lock_time,
|
|
})
|
|
.boxed()
|
|
}
|
|
|
|
pub fn v2_strategy() -> impl Strategy<Value = Self> {
|
|
(
|
|
vec(any::<TransparentInput>(), 0..10),
|
|
vec(any::<TransparentOutput>(), 0..10),
|
|
any::<LockTime>(),
|
|
option::of(any::<JoinSplitData<Bctv14Proof>>()),
|
|
)
|
|
.prop_map(
|
|
|(inputs, outputs, lock_time, joinsplit_data)| Transaction::V2 {
|
|
inputs: inputs,
|
|
outputs: outputs,
|
|
lock_time: lock_time,
|
|
joinsplit_data: joinsplit_data,
|
|
},
|
|
)
|
|
.boxed()
|
|
}
|
|
|
|
pub fn v3_strategy() -> impl Strategy<Value = Self> {
|
|
(
|
|
vec(any::<TransparentInput>(), 0..10),
|
|
vec(any::<TransparentOutput>(), 0..10),
|
|
any::<LockTime>(),
|
|
any::<BlockHeight>(),
|
|
option::of(any::<JoinSplitData<Bctv14Proof>>()),
|
|
)
|
|
.prop_map(
|
|
|(inputs, outputs, lock_time, expiry_height, joinsplit_data)| Transaction::V3 {
|
|
inputs: inputs,
|
|
outputs: outputs,
|
|
lock_time: lock_time,
|
|
expiry_height: expiry_height,
|
|
joinsplit_data: joinsplit_data,
|
|
},
|
|
)
|
|
.boxed()
|
|
}
|
|
|
|
pub fn v4_strategy() -> impl Strategy<Value = Self> {
|
|
(
|
|
vec(any::<TransparentInput>(), 0..10),
|
|
vec(any::<TransparentOutput>(), 0..10),
|
|
any::<LockTime>(),
|
|
any::<BlockHeight>(),
|
|
any::<i64>(),
|
|
option::of(any::<ShieldedData>()),
|
|
option::of(any::<JoinSplitData<Groth16Proof>>()),
|
|
)
|
|
.prop_map(
|
|
|(
|
|
inputs,
|
|
outputs,
|
|
lock_time,
|
|
expiry_height,
|
|
value_balance,
|
|
shielded_data,
|
|
joinsplit_data,
|
|
)| Transaction::V4 {
|
|
inputs: inputs,
|
|
outputs: outputs,
|
|
lock_time: lock_time,
|
|
expiry_height: expiry_height,
|
|
value_balance: value_balance,
|
|
shielded_data: shielded_data,
|
|
joinsplit_data: joinsplit_data,
|
|
},
|
|
)
|
|
.boxed()
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
impl Arbitrary for Transaction {
|
|
type Parameters = ();
|
|
|
|
fn arbitrary_with(_args: ()) -> Self::Strategy {
|
|
prop_oneof![
|
|
Self::v1_strategy(),
|
|
Self::v2_strategy(),
|
|
Self::v3_strategy(),
|
|
Self::v4_strategy()
|
|
]
|
|
.boxed()
|
|
}
|
|
|
|
type Strategy = BoxedStrategy<Self>;
|
|
}
|
|
|
|
#[test]
|
|
fn librustzcash_tx_deserialize_and_round_trip() {
|
|
let tx = Transaction::zcash_deserialize(&test_vectors::GENERIC_TESTNET_TX[..])
|
|
.expect("transaction test vector from librustzcash should deserialize");
|
|
|
|
let mut data2 = Vec::new();
|
|
tx.zcash_serialize(&mut data2).expect("tx should serialize");
|
|
|
|
assert_eq!(&test_vectors::GENERIC_TESTNET_TX[..], &data2[..]);
|
|
}
|
|
|
|
#[cfg(test)]
|
|
proptest! {
|
|
|
|
#[test]
|
|
fn transaction_roundtrip(tx in any::<Transaction>()) {
|
|
|
|
let mut data = Vec::new();
|
|
|
|
tx.zcash_serialize(&mut data).expect("tx should serialize");
|
|
|
|
let tx2 = Transaction::zcash_deserialize(&data[..]).expect("randomized tx should deserialize");
|
|
|
|
prop_assert_eq![tx, tx2];
|
|
}
|
|
}
|