Skip to content

Commit 3c9bac2

Browse files
authored
Add more V6 tests to zebra-chain, refactor OrchardZSA tests in zebra-test (#62)
* Rename orchard_..._zsa test vector files to orchard_zsa_..., same for structs and consts declardd there * Add tests for empty tx v6 into zebra-chain * Add V6 roundtrip tests based on ORCHARD_ZSA_WORKFLOW_BLOCKS test vectors to zebra-chain * Address PR #62 review comments * Improve OrchardZSA V6 round-trip and conversion tests
1 parent 6821d89 commit 3c9bac2

File tree

12 files changed

+170
-59
lines changed

12 files changed

+170
-59
lines changed

zebra-chain/src/primitives/zcash_primitives.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,16 @@ impl TryFrom<&Transaction> for zp_tx::Transaction {
180180
Transaction::V1 { .. }
181181
| Transaction::V2 { .. }
182182
| Transaction::V3 { .. }
183-
| Transaction::V4 { .. } => panic!("Zebra only uses librustzcash for V5 transactions"),
183+
| Transaction::V4 { .. } => {
184+
panic!("Zebra only uses librustzcash for V5/V6 transactions");
185+
}
184186
};
185187

186188
convert_tx_to_librustzcash(
187189
trans,
188-
network_upgrade.branch_id().expect("V5 txs have branch IDs"),
190+
network_upgrade
191+
.branch_id()
192+
.expect("V5/V6 txs have branch IDs"),
189193
)
190194
}
191195
}

zebra-chain/src/transaction/tests/vectors.rs

Lines changed: 121 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ lazy_static! {
3030
sapling_shielded_data: None,
3131
orchard_shielded_data: None,
3232
};
33+
34+
#[cfg(feature = "tx-v6")]
35+
pub static ref EMPTY_V6_TX: Transaction = Transaction::V6 {
36+
network_upgrade: NetworkUpgrade::Nu7,
37+
lock_time: LockTime::min_lock_time_timestamp(),
38+
expiry_height: block::Height(0),
39+
inputs: Vec::new(),
40+
outputs: Vec::new(),
41+
sapling_shielded_data: None,
42+
orchard_shielded_data: None,
43+
orchard_zsa_issue_data: None
44+
};
3345
}
3446

3547
/// Build a mock output list for pre-V5 transactions, with (index+1)
@@ -257,18 +269,9 @@ fn deserialize_large_transaction() {
257269
.expect_err("transaction should not deserialize due to its size");
258270
}
259271

260-
// Transaction V5 test vectors
261-
262-
/// An empty transaction v5, with no Orchard, Sapling, or Transparent data
263-
///
264-
/// empty transaction are invalid, but Zebra only checks this rule in
265-
/// zebra_consensus::transaction::Verifier
266-
#[test]
267-
fn empty_v5_round_trip() {
272+
fn tx_round_trip(tx: &Transaction) {
268273
let _init_guard = zebra_test::init();
269274

270-
let tx: &Transaction = &EMPTY_V5_TX;
271-
272275
let data = tx.zcash_serialize_to_vec().expect("tx should serialize");
273276
let tx2: &Transaction = &data
274277
.zcash_deserialize_into()
@@ -314,18 +317,47 @@ fn empty_v4_round_trip() {
314317
assert_eq!(data, data2, "data must be equal if structs are equal");
315318
}
316319

317-
/// Check if an empty V5 transaction can be deserialized by librustzcash too.
320+
/// An empty transaction v5, with no Orchard, Sapling, or Transparent data
321+
///
322+
/// empty transaction are invalid, but Zebra only checks this rule in
323+
/// zebra_consensus::transaction::Verifier
318324
#[test]
319-
fn empty_v5_librustzcash_round_trip() {
325+
fn empty_v5_round_trip() {
326+
tx_round_trip(&EMPTY_V5_TX)
327+
}
328+
329+
#[cfg(feature = "tx-v6")]
330+
/// An empty transaction v6, with no Orchard/OrchardZSA, Sapling, or Transparent data
331+
///
332+
/// empty transaction are invalid, but Zebra only checks this rule in
333+
/// zebra_consensus::transaction::Verifier
334+
#[test]
335+
fn empty_v6_round_trip() {
336+
tx_round_trip(&EMPTY_V6_TX)
337+
}
338+
339+
fn tx_librustzcash_round_trip(tx: &Transaction) {
320340
let _init_guard = zebra_test::init();
321341

322-
let tx: &Transaction = &EMPTY_V5_TX;
323342
let _alt_tx: zcash_primitives::transaction::Transaction = tx.try_into().expect(
324343
"librustzcash deserialization might work for empty zebra serialized transactions. \
325344
Hint: if empty transactions fail, but other transactions work, delete this test",
326345
);
327346
}
328347

348+
/// Check if an empty V5 transaction can be deserialized by librustzcash too.
349+
#[test]
350+
fn empty_v5_librustzcash_round_trip() {
351+
tx_librustzcash_round_trip(&EMPTY_V5_TX);
352+
}
353+
354+
#[cfg(feature = "tx-v6")]
355+
/// Check if an empty V6 transaction can be deserialized by librustzcash too.
356+
#[test]
357+
fn empty_v6_librustzcash_round_trip() {
358+
tx_librustzcash_round_trip(&EMPTY_V6_TX);
359+
}
360+
329361
/// Do a round-trip test on fake v5 transactions created from v4 transactions
330362
/// in the block test vectors.
331363
///
@@ -450,6 +482,54 @@ fn fake_v5_round_trip_for_network(network: Network) {
450482
}
451483
}
452484

485+
#[cfg(feature = "tx-v6")]
486+
/// Do a serialization round-trip on OrchardZSA workflow blocks and their V6
487+
/// transactions.
488+
#[test]
489+
fn v6_round_trip() {
490+
use zebra_test::vectors::ORCHARD_ZSA_WORKFLOW_BLOCKS;
491+
492+
let _init_guard = zebra_test::init();
493+
494+
for block_bytes in ORCHARD_ZSA_WORKFLOW_BLOCKS.iter() {
495+
let block = block_bytes
496+
.zcash_deserialize_into::<Block>()
497+
.expect("block is structurally valid");
498+
499+
// test full blocks
500+
let block_bytes2 = block
501+
.zcash_serialize_to_vec()
502+
.expect("vec serialization is infallible");
503+
504+
assert_eq!(
505+
block_bytes, &block_bytes2,
506+
"data must be equal if structs are equal"
507+
);
508+
509+
// test each transaction
510+
for tx in &block.transactions {
511+
let tx_bytes = tx
512+
.zcash_serialize_to_vec()
513+
.expect("vec serialization is infallible");
514+
515+
let tx2 = tx_bytes
516+
.zcash_deserialize_into::<Transaction>()
517+
.expect("tx is structurally valid");
518+
519+
assert_eq!(tx.as_ref(), &tx2);
520+
521+
let tx_bytes2 = tx2
522+
.zcash_serialize_to_vec()
523+
.expect("vec serialization is infallible");
524+
525+
assert_eq!(
526+
tx_bytes, tx_bytes2,
527+
"data must be equal if structs are equal"
528+
);
529+
}
530+
}
531+
}
532+
453533
#[test]
454534
fn invalid_orchard_nullifier() {
455535
let _init_guard = zebra_test::init();
@@ -549,6 +629,34 @@ fn fake_v5_librustzcash_round_trip_for_network(network: Network) {
549629
}
550630
}
551631

632+
#[cfg(feature = "tx-v6")]
633+
/// Confirms each V6 transaction in the OrchardZSA test blocks converts to librustzcash’s
634+
/// transaction type without error.
635+
#[test]
636+
fn v6_librustzcash_tx_conversion() {
637+
use zebra_test::vectors::ORCHARD_ZSA_WORKFLOW_BLOCKS;
638+
639+
let _init_guard = zebra_test::init();
640+
641+
for block_bytes in ORCHARD_ZSA_WORKFLOW_BLOCKS.iter() {
642+
let block = block_bytes
643+
.zcash_deserialize_into::<Block>()
644+
.expect("block is structurally valid");
645+
646+
// Test each V6 transaction
647+
for tx in block
648+
.transactions
649+
.iter()
650+
.filter(|tx| matches!(tx.as_ref(), &Transaction::V6 { .. }))
651+
{
652+
let _alt_tx: zcash_primitives::transaction::Transaction = tx
653+
.as_ref()
654+
.try_into()
655+
.expect("librustzcash conversion must work for zebra transactions");
656+
}
657+
}
658+
}
659+
552660
#[test]
553661
fn zip244_round_trip() -> Result<()> {
554662
let _init_guard = zebra_test::init();

zebra-consensus/src/orchard_zsa/tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ use zebra_chain::{
2424

2525
use zebra_test::{
2626
transcript::{ExpectedTranscriptError, Transcript},
27-
vectors::ORCHARD_WORKFLOW_BLOCKS_ZSA,
27+
vectors::ORCHARD_ZSA_WORKFLOW_BLOCKS,
2828
};
2929

3030
use crate::{block::Request, Config};
3131

3232
fn create_transcript_data() -> impl Iterator<Item = (Request, Result<Hash, ExpectedTranscriptError>)>
3333
{
34-
let workflow_blocks = ORCHARD_WORKFLOW_BLOCKS_ZSA.iter().map(|block_bytes| {
34+
let workflow_blocks = ORCHARD_ZSA_WORKFLOW_BLOCKS.iter().map(|block_bytes| {
3535
Arc::new(Block::zcash_deserialize(&block_bytes[..]).expect("block should deserialize"))
3636
});
3737

zebra-consensus/src/primitives/halo2/tests.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ use zebra_chain::{
2424

2525
use crate::primitives::halo2::*;
2626

27-
// FIXME: Where is this function called from?
2827
#[allow(dead_code, clippy::print_stdout)]
2928
fn generate_test_vectors<Flavor: ShieldedDataFlavor>()
3029
where
@@ -199,7 +198,7 @@ async fn verify_generated_halo2_proofs_vanilla() {
199198
#[cfg(feature = "tx-v6")]
200199
#[tokio::test(flavor = "multi_thread")]
201200
async fn verify_generated_halo2_proofs_zsa() {
202-
verify_generated_halo2_proofs::<OrchardZSA>(&zebra_test::vectors::ORCHARD_SHIELDED_DATA_ZSA)
201+
verify_generated_halo2_proofs::<OrchardZSA>(&zebra_test::vectors::ORCHARD_ZSA_SHIELDED_DATA)
203202
.await
204203
}
205204

@@ -291,7 +290,7 @@ async fn correctly_err_on_invalid_halo2_proofs_vanilla() {
291290
#[tokio::test(flavor = "multi_thread")]
292291
async fn correctly_err_on_invalid_halo2_proofs_zsa() {
293292
correctly_err_on_invalid_halo2_proofs::<OrchardZSA>(
294-
&zebra_test::vectors::ORCHARD_SHIELDED_DATA_ZSA,
293+
&zebra_test::vectors::ORCHARD_ZSA_SHIELDED_DATA,
295294
)
296295
.await
297296
}

zebra-test/src/vectors.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,20 @@ mod orchard_note_encryption;
88
mod orchard_shielded_data;
99

1010
#[cfg(feature = "tx-v6")]
11-
mod orchard_shielded_data_zsa;
11+
mod orchard_zsa_shielded_data;
1212

1313
#[cfg(feature = "tx-v6")]
14-
mod orchard_workflow_blocks_zsa;
14+
mod orchard_zsa_workflow_blocks;
1515

1616
pub use block::*;
1717
pub use orchard_note_encryption::*;
1818
pub use orchard_shielded_data::*;
1919

2020
#[cfg(feature = "tx-v6")]
21-
pub use orchard_shielded_data_zsa::*;
21+
pub use orchard_zsa_shielded_data::*;
2222

2323
#[cfg(feature = "tx-v6")]
24-
pub use orchard_workflow_blocks_zsa::*;
24+
pub use orchard_zsa_workflow_blocks::*;
2525

2626
/// A testnet transaction test vector
2727
///

zebra-test/src/vectors/orchard-shielded-data-zsa-1.txt renamed to zebra-test/src/vectors/orchard-zsa-shielded-data-1.txt

File renamed without changes.

zebra-test/src/vectors/orchard-shielded-data-zsa-2.txt renamed to zebra-test/src/vectors/orchard-zsa-shielded-data-2.txt

File renamed without changes.

zebra-test/src/vectors/orchard-shielded-data-zsa-3.txt renamed to zebra-test/src/vectors/orchard-zsa-shielded-data-3.txt

File renamed without changes.

zebra-test/src/vectors/orchard-shielded-data-zsa-4.txt renamed to zebra-test/src/vectors/orchard-zsa-shielded-data-4.txt

File renamed without changes.

zebra-test/src/vectors/orchard_shielded_data_zsa.rs

Lines changed: 0 additions & 34 deletions
This file was deleted.

0 commit comments

Comments
 (0)