From a7b0a521d51af4af7294892604c34087e0414330 Mon Sep 17 00:00:00 2001 From: teor Date: Mon, 26 Jul 2021 13:10:24 +1000 Subject: [PATCH] rustfmt inside nullifier and utxo proptests (#2515) * rustfmt inside nullifier and utxo proptests * Fix a comment typo * Use a `chain` binding to simplify test assertions --- .../src/service/check/tests/nullifier.rs | 387 ++++++++---------- zebra-state/src/service/check/tests/utxo.rs | 194 +++++---- 2 files changed, 292 insertions(+), 289 deletions(-) diff --git a/zebra-state/src/service/check/tests/nullifier.rs b/zebra-state/src/service/check/tests/nullifier.rs index 735c2fa6..2251d693 100644 --- a/zebra-state/src/service/check/tests/nullifier.rs +++ b/zebra-state/src/service/check/tests/nullifier.rs @@ -44,7 +44,7 @@ proptest! { .unwrap_or(DEFAULT_NULLIFIER_PROPTEST_CASES)) )] -// sprout + // sprout /// Make sure an arbitrary sprout nullifier is accepted by state contextual validation. /// @@ -52,8 +52,8 @@ proptest! { /// (And that the test infrastructure generally works.) #[test] fn accept_distinct_arbitrary_sprout_nullifiers_in_one_block( - mut joinsplit in TypeNameToDebug::>::arbitrary(), - joinsplit_data in TypeNameToDebug::>::arbitrary(), + mut joinsplit in TypeNameToDebug::>::arbitrary(), + joinsplit_data in TypeNameToDebug::>::arbitrary(), use_finalized_state in any::(), ) { zebra_test::init(); @@ -70,9 +70,7 @@ proptest! { // convert the coinbase transaction to a version that the non-finalized state will accept block1.transactions[0] = transaction_v4_from_coinbase(&block1.transactions[0]).into(); - block1 - .transactions - .push(transaction.into()); + block1.transactions.push(transaction.into()); let (mut state, _genesis) = new_state_with_mainnet_genesis(); let previous_mem = state.mem.clone(); @@ -90,12 +88,15 @@ proptest! { prop_assert!(state.mem.eq_internal_state(&previous_mem)); // the finalized state has the nullifiers - prop_assert!(state.disk.contains_sprout_nullifier(&expected_nullifiers[0])); - prop_assert!(state.disk.contains_sprout_nullifier(&expected_nullifiers[1])); + prop_assert!(state + .disk + .contains_sprout_nullifier(&expected_nullifiers[0])); + prop_assert!(state + .disk + .contains_sprout_nullifier(&expected_nullifiers[1])); } else { let block1 = Arc::new(block1).prepare(); - let commit_result = - state.validate_and_commit(block1.clone()); + let commit_result = state.validate_and_commit(block1.clone()); // the block was committed prop_assert_eq!(commit_result, Ok(())); @@ -106,8 +107,12 @@ proptest! { // the non-finalized state has the nullifiers prop_assert_eq!(state.mem.chain_set.len(), 1); - prop_assert!(state.mem.best_contains_sprout_nullifier(&expected_nullifiers[0])); - prop_assert!(state.mem.best_contains_sprout_nullifier(&expected_nullifiers[1])); + prop_assert!(state + .mem + .best_contains_sprout_nullifier(&expected_nullifiers[0])); + prop_assert!(state + .mem + .best_contains_sprout_nullifier(&expected_nullifiers[1])); } } @@ -115,8 +120,8 @@ proptest! { /// if they come from the same JoinSplit. #[test] fn reject_duplicate_sprout_nullifiers_in_joinsplit( - mut joinsplit in TypeNameToDebug::>::arbitrary(), - joinsplit_data in TypeNameToDebug::>::arbitrary(), + mut joinsplit in TypeNameToDebug::>::arbitrary(), + joinsplit_data in TypeNameToDebug::>::arbitrary(), ) { zebra_test::init(); @@ -133,27 +138,23 @@ proptest! { block1.transactions[0] = transaction_v4_from_coinbase(&block1.transactions[0]).into(); - block1 - .transactions - .push(transaction.into()); + block1.transactions.push(transaction.into()); let (mut state, genesis) = new_state_with_mainnet_genesis(); let previous_mem = state.mem.clone(); let block1 = Arc::new(block1).prepare(); - let commit_result = - state.validate_and_commit(block1); + let commit_result = state.validate_and_commit(block1); // if the random proptest data produces other errors, // we might need to just check `is_err()` here prop_assert_eq!( commit_result, - Err( - DuplicateSproutNullifier { - nullifier: duplicate_nullifier, - in_finalized_state: false, - }.into() - ) + Err(DuplicateSproutNullifier { + nullifier: duplicate_nullifier, + in_finalized_state: false, + } + .into()) ); // block was rejected prop_assert_eq!(Some((Height(0), genesis.hash)), state.best_tip()); @@ -164,9 +165,9 @@ proptest! { /// if they come from different JoinSplits in the same JoinSplitData/Transaction. #[test] fn reject_duplicate_sprout_nullifiers_in_transaction( - mut joinsplit1 in TypeNameToDebug::>::arbitrary(), - mut joinsplit2 in TypeNameToDebug::>::arbitrary(), - joinsplit_data in TypeNameToDebug::>::arbitrary(), + mut joinsplit1 in TypeNameToDebug::>::arbitrary(), + mut joinsplit2 in TypeNameToDebug::>::arbitrary(), + joinsplit_data in TypeNameToDebug::>::arbitrary(), ) { zebra_test::init(); @@ -174,38 +175,37 @@ proptest! { .zcash_deserialize_into::() .expect("block should deserialize"); - make_distinct_nullifiers(&mut joinsplit1.nullifiers.iter_mut().chain(joinsplit2.nullifiers.iter_mut())); + make_distinct_nullifiers( + &mut joinsplit1 + .nullifiers + .iter_mut() + .chain(joinsplit2.nullifiers.iter_mut()), + ); // create a double-spend across two joinsplits let duplicate_nullifier = joinsplit1.nullifiers[0]; joinsplit2.nullifiers[0] = duplicate_nullifier; - let transaction = transaction_v4_with_joinsplit_data( - joinsplit_data.0, - [joinsplit1.0, joinsplit2.0] - ); + let transaction = + transaction_v4_with_joinsplit_data(joinsplit_data.0, [joinsplit1.0, joinsplit2.0]); block1.transactions[0] = transaction_v4_from_coinbase(&block1.transactions[0]).into(); - block1 - .transactions - .push(transaction.into()); + block1.transactions.push(transaction.into()); let (mut state, genesis) = new_state_with_mainnet_genesis(); let previous_mem = state.mem.clone(); let block1 = Arc::new(block1).prepare(); - let commit_result = - state.validate_and_commit(block1); + let commit_result = state.validate_and_commit(block1); prop_assert_eq!( commit_result, - Err( - DuplicateSproutNullifier { - nullifier: duplicate_nullifier, - in_finalized_state: false, - }.into() - ) + Err(DuplicateSproutNullifier { + nullifier: duplicate_nullifier, + in_finalized_state: false, + } + .into()) ); prop_assert_eq!(Some((Height(0), genesis.hash)), state.best_tip()); prop_assert!(state.mem.eq_internal_state(&previous_mem)); @@ -215,10 +215,10 @@ proptest! { /// if they come from different transactions in the same block. #[test] fn reject_duplicate_sprout_nullifiers_in_block( - mut joinsplit1 in TypeNameToDebug::>::arbitrary(), - mut joinsplit2 in TypeNameToDebug::>::arbitrary(), - joinsplit_data1 in TypeNameToDebug::>::arbitrary(), - joinsplit_data2 in TypeNameToDebug::>::arbitrary(), + mut joinsplit1 in TypeNameToDebug::>::arbitrary(), + mut joinsplit2 in TypeNameToDebug::>::arbitrary(), + joinsplit_data1 in TypeNameToDebug::>::arbitrary(), + joinsplit_data2 in TypeNameToDebug::>::arbitrary(), ) { zebra_test::init(); @@ -226,7 +226,12 @@ proptest! { .zcash_deserialize_into::() .expect("block should deserialize"); - make_distinct_nullifiers(&mut joinsplit1.nullifiers.iter_mut().chain(joinsplit2.nullifiers.iter_mut())); + make_distinct_nullifiers( + &mut joinsplit1 + .nullifiers + .iter_mut() + .chain(joinsplit2.nullifiers.iter_mut()), + ); // create a double-spend across two transactions let duplicate_nullifier = joinsplit1.nullifiers[0]; @@ -245,17 +250,15 @@ proptest! { let previous_mem = state.mem.clone(); let block1 = Arc::new(block1).prepare(); - let commit_result = - state.validate_and_commit(block1); + let commit_result = state.validate_and_commit(block1); prop_assert_eq!( commit_result, - Err( - DuplicateSproutNullifier { - nullifier: duplicate_nullifier, - in_finalized_state: false, - }.into() - ) + Err(DuplicateSproutNullifier { + nullifier: duplicate_nullifier, + in_finalized_state: false, + } + .into()) ); prop_assert_eq!(Some((Height(0), genesis.hash)), state.best_tip()); prop_assert!(state.mem.eq_internal_state(&previous_mem)); @@ -265,10 +268,10 @@ proptest! { /// if they come from different blocks in the same chain. #[test] fn reject_duplicate_sprout_nullifiers_in_chain( - mut joinsplit1 in TypeNameToDebug::>::arbitrary(), - mut joinsplit2 in TypeNameToDebug::>::arbitrary(), - joinsplit_data1 in TypeNameToDebug::>::arbitrary(), - joinsplit_data2 in TypeNameToDebug::>::arbitrary(), + mut joinsplit1 in TypeNameToDebug::>::arbitrary(), + mut joinsplit2 in TypeNameToDebug::>::arbitrary(), + joinsplit_data1 in TypeNameToDebug::>::arbitrary(), + joinsplit_data2 in TypeNameToDebug::>::arbitrary(), duplicate_in_finalized_state in any::(), ) { zebra_test::init(); @@ -280,7 +283,12 @@ proptest! { .zcash_deserialize_into::() .expect("block should deserialize"); - make_distinct_nullifiers(&mut joinsplit1.nullifiers.iter_mut().chain(joinsplit2.nullifiers.iter_mut())); + make_distinct_nullifiers( + &mut joinsplit1 + .nullifiers + .iter_mut() + .chain(joinsplit2.nullifiers.iter_mut()), + ); let expected_nullifiers = joinsplit1.nullifiers; // create a double-spend across two blocks @@ -293,12 +301,8 @@ proptest! { block1.transactions[0] = transaction_v4_from_coinbase(&block1.transactions[0]).into(); block2.transactions[0] = transaction_v4_from_coinbase(&block2.transactions[0]).into(); - block1 - .transactions - .push(transaction1.into()); - block2 - .transactions - .push(transaction2.into()); + block1.transactions.push(transaction1.into()); + block2.transactions.push(transaction2.into()); let (mut state, _genesis) = new_state_with_mainnet_genesis(); let mut previous_mem = state.mem.clone(); @@ -312,43 +316,48 @@ proptest! { prop_assert_eq!(Some((Height(1), block1.hash)), state.best_tip()); prop_assert!(commit_result.is_ok()); prop_assert!(state.mem.eq_internal_state(&previous_mem)); - prop_assert!(state.disk.contains_sprout_nullifier(&expected_nullifiers[0])); - prop_assert!(state.disk.contains_sprout_nullifier(&expected_nullifiers[1])); + prop_assert!(state + .disk + .contains_sprout_nullifier(&expected_nullifiers[0])); + prop_assert!(state + .disk + .contains_sprout_nullifier(&expected_nullifiers[1])); block1_hash = block1.hash; } else { let block1 = Arc::new(block1).prepare(); - let commit_result = - state.validate_and_commit(block1.clone()); + let commit_result = state.validate_and_commit(block1.clone()); prop_assert_eq!(commit_result, Ok(())); prop_assert_eq!(Some((Height(1), block1.hash)), state.best_tip()); prop_assert!(!state.mem.eq_internal_state(&previous_mem)); - prop_assert!(state.mem.best_contains_sprout_nullifier(&expected_nullifiers[0])); - prop_assert!(state.mem.best_contains_sprout_nullifier(&expected_nullifiers[1])); + prop_assert!(state + .mem + .best_contains_sprout_nullifier(&expected_nullifiers[0])); + prop_assert!(state + .mem + .best_contains_sprout_nullifier(&expected_nullifiers[1])); block1_hash = block1.hash; previous_mem = state.mem.clone(); } let block2 = Arc::new(block2).prepare(); - let commit_result = - state.validate_and_commit(block2); + let commit_result = state.validate_and_commit(block2); prop_assert_eq!( commit_result, - Err( - DuplicateSproutNullifier { - nullifier: duplicate_nullifier, - in_finalized_state: duplicate_in_finalized_state, - }.into() - ) + Err(DuplicateSproutNullifier { + nullifier: duplicate_nullifier, + in_finalized_state: duplicate_in_finalized_state, + } + .into()) ); prop_assert_eq!(Some((Height(1), block1_hash)), state.best_tip()); prop_assert!(state.mem.eq_internal_state(&previous_mem)); } -// sapling + // sapling /// Make sure an arbitrary sapling nullifier is accepted by state contextual validation. /// @@ -356,8 +365,8 @@ proptest! { /// (And that the test infrastructure generally works.) #[test] fn accept_distinct_arbitrary_sapling_nullifiers_in_one_block( - spend in TypeNameToDebug::>::arbitrary(), - sapling_shielded_data in TypeNameToDebug::>::arbitrary(), + spend in TypeNameToDebug::>::arbitrary(), + sapling_shielded_data in TypeNameToDebug::>::arbitrary(), use_finalized_state in any::(), ) { zebra_test::init(); @@ -368,17 +377,13 @@ proptest! { let expected_nullifier = spend.nullifier; - let transaction = transaction_v4_with_sapling_shielded_data( - sapling_shielded_data.0, - [spend.0] - ); + let transaction = + transaction_v4_with_sapling_shielded_data(sapling_shielded_data.0, [spend.0]); // convert the coinbase transaction to a version that the non-finalized state will accept block1.transactions[0] = transaction_v4_from_coinbase(&block1.transactions[0]).into(); - block1 - .transactions - .push(transaction.into()); + block1.transactions.push(transaction.into()); let (mut state, _genesis) = new_state_with_mainnet_genesis(); let previous_mem = state.mem.clone(); @@ -394,13 +399,14 @@ proptest! { prop_assert!(state.disk.contains_sapling_nullifier(&expected_nullifier)); } else { let block1 = Arc::new(block1).prepare(); - let commit_result = - state.validate_and_commit(block1.clone()); + let commit_result = state.validate_and_commit(block1.clone()); prop_assert_eq!(commit_result, Ok(())); prop_assert_eq!(Some((Height(1), block1.hash)), state.best_tip()); prop_assert!(!state.mem.eq_internal_state(&previous_mem)); - prop_assert!(state.mem.best_contains_sapling_nullifier(&expected_nullifier)); + prop_assert!(state + .mem + .best_contains_sapling_nullifier(&expected_nullifier)); } } @@ -408,9 +414,9 @@ proptest! { /// if they come from different Spends in the same sapling::ShieldedData/Transaction. #[test] fn reject_duplicate_sapling_nullifiers_in_transaction( - spend1 in TypeNameToDebug::>::arbitrary(), - mut spend2 in TypeNameToDebug::>::arbitrary(), - sapling_shielded_data in TypeNameToDebug::>::arbitrary(), + spend1 in TypeNameToDebug::>::arbitrary(), + mut spend2 in TypeNameToDebug::>::arbitrary(), + sapling_shielded_data in TypeNameToDebug::>::arbitrary(), ) { zebra_test::init(); @@ -429,25 +435,21 @@ proptest! { block1.transactions[0] = transaction_v4_from_coinbase(&block1.transactions[0]).into(); - block1 - .transactions - .push(transaction.into()); + block1.transactions.push(transaction.into()); let (mut state, genesis) = new_state_with_mainnet_genesis(); let previous_mem = state.mem.clone(); let block1 = Arc::new(block1).prepare(); - let commit_result = - state.validate_and_commit(block1); + let commit_result = state.validate_and_commit(block1); prop_assert_eq!( commit_result, - Err( - DuplicateSaplingNullifier { - nullifier: duplicate_nullifier, - in_finalized_state: false, - }.into() - ) + Err(DuplicateSaplingNullifier { + nullifier: duplicate_nullifier, + in_finalized_state: false, + } + .into()) ); prop_assert_eq!(Some((Height(0), genesis.hash)), state.best_tip()); prop_assert!(state.mem.eq_internal_state(&previous_mem)); @@ -457,10 +459,10 @@ proptest! { /// if they come from different transactions in the same block. #[test] fn reject_duplicate_sapling_nullifiers_in_block( - spend1 in TypeNameToDebug::>::arbitrary(), - mut spend2 in TypeNameToDebug::>::arbitrary(), - sapling_shielded_data1 in TypeNameToDebug::>::arbitrary(), - sapling_shielded_data2 in TypeNameToDebug::>::arbitrary(), + spend1 in TypeNameToDebug::>::arbitrary(), + mut spend2 in TypeNameToDebug::>::arbitrary(), + sapling_shielded_data1 in TypeNameToDebug::>::arbitrary(), + sapling_shielded_data2 in TypeNameToDebug::>::arbitrary(), ) { zebra_test::init(); @@ -472,14 +474,10 @@ proptest! { let duplicate_nullifier = spend1.nullifier; spend2.nullifier = duplicate_nullifier; - let transaction1 = transaction_v4_with_sapling_shielded_data( - sapling_shielded_data1.0, - [spend1.0] - ); - let transaction2 = transaction_v4_with_sapling_shielded_data( - sapling_shielded_data2.0, - [spend2.0] - ); + let transaction1 = + transaction_v4_with_sapling_shielded_data(sapling_shielded_data1.0, [spend1.0]); + let transaction2 = + transaction_v4_with_sapling_shielded_data(sapling_shielded_data2.0, [spend2.0]); block1.transactions[0] = transaction_v4_from_coinbase(&block1.transactions[0]).into(); @@ -491,17 +489,15 @@ proptest! { let previous_mem = state.mem.clone(); let block1 = Arc::new(block1).prepare(); - let commit_result = - state.validate_and_commit(block1); + let commit_result = state.validate_and_commit(block1); prop_assert_eq!( commit_result, - Err( - DuplicateSaplingNullifier { - nullifier: duplicate_nullifier, - in_finalized_state: false, - }.into() - ) + Err(DuplicateSaplingNullifier { + nullifier: duplicate_nullifier, + in_finalized_state: false, + } + .into()) ); prop_assert_eq!(Some((Height(0), genesis.hash)), state.best_tip()); prop_assert!(state.mem.eq_internal_state(&previous_mem)); @@ -511,10 +507,10 @@ proptest! { /// if they come from different blocks in the same chain. #[test] fn reject_duplicate_sapling_nullifiers_in_chain( - spend1 in TypeNameToDebug::>::arbitrary(), - mut spend2 in TypeNameToDebug::>::arbitrary(), - sapling_shielded_data1 in TypeNameToDebug::>::arbitrary(), - sapling_shielded_data2 in TypeNameToDebug::>::arbitrary(), + spend1 in TypeNameToDebug::>::arbitrary(), + mut spend2 in TypeNameToDebug::>::arbitrary(), + sapling_shielded_data1 in TypeNameToDebug::>::arbitrary(), + sapling_shielded_data2 in TypeNameToDebug::>::arbitrary(), duplicate_in_finalized_state in any::(), ) { zebra_test::init(); @@ -530,24 +526,16 @@ proptest! { let duplicate_nullifier = spend1.nullifier; spend2.nullifier = duplicate_nullifier; - let transaction1 = transaction_v4_with_sapling_shielded_data( - sapling_shielded_data1.0, - [spend1.0] - ); - let transaction2 = transaction_v4_with_sapling_shielded_data( - sapling_shielded_data2.0, - [spend2.0] - ); + let transaction1 = + transaction_v4_with_sapling_shielded_data(sapling_shielded_data1.0, [spend1.0]); + let transaction2 = + transaction_v4_with_sapling_shielded_data(sapling_shielded_data2.0, [spend2.0]); block1.transactions[0] = transaction_v4_from_coinbase(&block1.transactions[0]).into(); block2.transactions[0] = transaction_v4_from_coinbase(&block2.transactions[0]).into(); - block1 - .transactions - .push(transaction1.into()); - block2 - .transactions - .push(transaction2.into()); + block1.transactions.push(transaction1.into()); + block2.transactions.push(transaction2.into()); let (mut state, _genesis) = new_state_with_mainnet_genesis(); let mut previous_mem = state.mem.clone(); @@ -566,36 +554,35 @@ proptest! { block1_hash = block1.hash; } else { let block1 = Arc::new(block1).prepare(); - let commit_result = - state.validate_and_commit(block1.clone()); + let commit_result = state.validate_and_commit(block1.clone()); prop_assert_eq!(commit_result, Ok(())); prop_assert_eq!(Some((Height(1), block1.hash)), state.best_tip()); prop_assert!(!state.mem.eq_internal_state(&previous_mem)); - prop_assert!(state.mem.best_contains_sapling_nullifier(&duplicate_nullifier)); + prop_assert!(state + .mem + .best_contains_sapling_nullifier(&duplicate_nullifier)); block1_hash = block1.hash; previous_mem = state.mem.clone(); } let block2 = Arc::new(block2).prepare(); - let commit_result = - state.validate_and_commit(block2); + let commit_result = state.validate_and_commit(block2); prop_assert_eq!( commit_result, - Err( - DuplicateSaplingNullifier { - nullifier: duplicate_nullifier, - in_finalized_state: duplicate_in_finalized_state, - }.into() - ) + Err(DuplicateSaplingNullifier { + nullifier: duplicate_nullifier, + in_finalized_state: duplicate_in_finalized_state, + } + .into()) ); prop_assert_eq!(Some((Height(1), block1_hash)), state.best_tip()); prop_assert!(state.mem.eq_internal_state(&previous_mem)); } -// orchard + // orchard /// Make sure an arbitrary orchard nullifier is accepted by state contextual validation. /// @@ -617,15 +604,13 @@ proptest! { let transaction = transaction_v5_with_orchard_shielded_data( orchard_shielded_data.0, - [authorized_action.0] + [authorized_action.0], ); // convert the coinbase transaction to a version that the non-finalized state will accept block1.transactions[0] = transaction_v4_from_coinbase(&block1.transactions[0]).into(); - block1 - .transactions - .push(transaction.into()); + block1.transactions.push(transaction.into()); let (mut state, _genesis) = new_state_with_mainnet_genesis(); let previous_mem = state.mem.clone(); @@ -641,13 +626,14 @@ proptest! { prop_assert!(state.disk.contains_orchard_nullifier(&expected_nullifier)); } else { let block1 = Arc::new(block1).prepare(); - let commit_result = - state.validate_and_commit(block1.clone()); + let commit_result = state.validate_and_commit(block1.clone()); prop_assert_eq!(commit_result, Ok(())); prop_assert_eq!(Some((Height(1), block1.hash)), state.best_tip()); prop_assert!(!state.mem.eq_internal_state(&previous_mem)); - prop_assert!(state.mem.best_contains_orchard_nullifier(&expected_nullifier)); + prop_assert!(state + .mem + .best_contains_orchard_nullifier(&expected_nullifier)); } } @@ -676,25 +662,21 @@ proptest! { block1.transactions[0] = transaction_v4_from_coinbase(&block1.transactions[0]).into(); - block1 - .transactions - .push(transaction.into()); + block1.transactions.push(transaction.into()); let (mut state, genesis) = new_state_with_mainnet_genesis(); let previous_mem = state.mem.clone(); let block1 = Arc::new(block1).prepare(); - let commit_result = - state.validate_and_commit(block1); + let commit_result = state.validate_and_commit(block1); prop_assert_eq!( commit_result, - Err( - DuplicateOrchardNullifier { - nullifier: duplicate_nullifier, - in_finalized_state: false, - }.into() - ) + Err(DuplicateOrchardNullifier { + nullifier: duplicate_nullifier, + in_finalized_state: false, + } + .into()) ); prop_assert_eq!(Some((Height(0), genesis.hash)), state.best_tip()); prop_assert!(state.mem.eq_internal_state(&previous_mem)); @@ -721,11 +703,11 @@ proptest! { let transaction1 = transaction_v5_with_orchard_shielded_data( orchard_shielded_data1.0, - [authorized_action1.0] + [authorized_action1.0], ); let transaction2 = transaction_v5_with_orchard_shielded_data( orchard_shielded_data2.0, - [authorized_action2.0] + [authorized_action2.0], ); block1.transactions[0] = transaction_v4_from_coinbase(&block1.transactions[0]).into(); @@ -738,17 +720,15 @@ proptest! { let previous_mem = state.mem.clone(); let block1 = Arc::new(block1).prepare(); - let commit_result = - state.validate_and_commit(block1); + let commit_result = state.validate_and_commit(block1); prop_assert_eq!( commit_result, - Err( - DuplicateOrchardNullifier { - nullifier: duplicate_nullifier, - in_finalized_state: false, - }.into() - ) + Err(DuplicateOrchardNullifier { + nullifier: duplicate_nullifier, + in_finalized_state: false, + } + .into()) ); prop_assert_eq!(Some((Height(0), genesis.hash)), state.best_tip()); prop_assert!(state.mem.eq_internal_state(&previous_mem)); @@ -779,22 +759,18 @@ proptest! { let transaction1 = transaction_v5_with_orchard_shielded_data( orchard_shielded_data1.0, - [authorized_action1.0] + [authorized_action1.0], ); let transaction2 = transaction_v5_with_orchard_shielded_data( orchard_shielded_data2.0, - [authorized_action2.0] + [authorized_action2.0], ); block1.transactions[0] = transaction_v4_from_coinbase(&block1.transactions[0]).into(); block2.transactions[0] = transaction_v4_from_coinbase(&block2.transactions[0]).into(); - block1 - .transactions - .push(transaction1.into()); - block2 - .transactions - .push(transaction2.into()); + block1.transactions.push(transaction1.into()); + block2.transactions.push(transaction2.into()); let (mut state, _genesis) = new_state_with_mainnet_genesis(); let mut previous_mem = state.mem.clone(); @@ -813,30 +789,29 @@ proptest! { block1_hash = block1.hash; } else { let block1 = Arc::new(block1).prepare(); - let commit_result = - state.validate_and_commit(block1.clone()); + let commit_result = state.validate_and_commit(block1.clone()); prop_assert_eq!(commit_result, Ok(())); prop_assert_eq!(Some((Height(1), block1.hash)), state.best_tip()); prop_assert!(!state.mem.eq_internal_state(&previous_mem)); - prop_assert!(state.mem.best_contains_orchard_nullifier(&duplicate_nullifier)); + prop_assert!(state + .mem + .best_contains_orchard_nullifier(&duplicate_nullifier)); block1_hash = block1.hash; previous_mem = state.mem.clone(); } let block2 = Arc::new(block2).prepare(); - let commit_result = - state.validate_and_commit(block2); + let commit_result = state.validate_and_commit(block2); prop_assert_eq!( commit_result, - Err( - DuplicateOrchardNullifier { - nullifier: duplicate_nullifier, - in_finalized_state: duplicate_in_finalized_state, - }.into() - ) + Err(DuplicateOrchardNullifier { + nullifier: duplicate_nullifier, + in_finalized_state: duplicate_in_finalized_state, + } + .into()) ); prop_assert_eq!(Some((Height(1), block1_hash)), state.best_tip()); prop_assert!(state.mem.eq_internal_state(&previous_mem)); diff --git a/zebra-state/src/service/check/tests/utxo.rs b/zebra-state/src/service/check/tests/utxo.rs index b1aaebbb..6a745b89 100644 --- a/zebra-state/src/service/check/tests/utxo.rs +++ b/zebra-state/src/service/check/tests/utxo.rs @@ -66,7 +66,10 @@ proptest! { let output_transaction = transaction_v4_with_transparent_data([], [output.0]); // create a spend - let expected_outpoint = transparent::OutPoint { hash: output_transaction.hash(), index: 0 }; + let expected_outpoint = transparent::OutPoint { + hash: output_transaction.hash(), + index: 0, + }; prevout_input.set_outpoint(expected_outpoint); let spend_transaction = transaction_v4_with_transparent_data([prevout_input.0], []); @@ -98,8 +101,7 @@ proptest! { prop_assert!(state.mem.any_utxo(&expected_outpoint).is_none()); } else { let block1 = Arc::new(block1).prepare(); - let commit_result = - state.validate_and_commit(block1.clone()); + let commit_result = state.validate_and_commit(block1.clone()); // the block was committed prop_assert_eq!(commit_result, Ok(())); @@ -108,11 +110,17 @@ proptest! { // the block data is in the non-finalized state prop_assert!(!state.mem.eq_internal_state(&previous_mem)); - // the non-finalized state has the spent its own UTXO + // the non-finalized state has created and spent the UTXO prop_assert_eq!(state.mem.chain_set.len(), 1); - prop_assert!(!state.mem.chain_set.iter().next().unwrap().unspent_utxos().contains_key(&expected_outpoint)); - prop_assert!(state.mem.chain_set.iter().next().unwrap().created_utxos.contains_key(&expected_outpoint)); - prop_assert!(state.mem.chain_set.iter().next().unwrap().spent_utxos.contains(&expected_outpoint)); + let chain = state + .mem + .chain_set + .iter() + .next() + .unwrap(); + prop_assert!(!chain.unspent_utxos().contains_key(&expected_outpoint)); + prop_assert!(chain.created_utxos.contains_key(&expected_outpoint)); + prop_assert!(chain.spent_utxos.contains(&expected_outpoint)); // the finalized state does not have the UTXO prop_assert!(state.disk.utxo(&expected_outpoint).is_none()); @@ -140,10 +148,15 @@ proptest! { .zcash_deserialize_into::() .expect("block should deserialize"); - let TestState { mut state, block1, .. } = new_state_with_mainnet_transparent_data([], [output.0], use_finalized_state_output); + let TestState { + mut state, block1, .. + } = new_state_with_mainnet_transparent_data([], [output.0], use_finalized_state_output); let previous_mem = state.mem.clone(); - let expected_outpoint = transparent::OutPoint { hash: block1.transactions[1].hash(), index: 0 }; + let expected_outpoint = transparent::OutPoint { + hash: block1.transactions[1].hash(), + index: 0, + }; prevout_input.set_outpoint(expected_outpoint); let spend_transaction = transaction_v4_with_transparent_data([prevout_input.0], []); @@ -151,9 +164,7 @@ proptest! { // convert the coinbase transaction to a version that the non-finalized state will accept block2.transactions[0] = transaction_v4_from_coinbase(&block2.transactions[0]).into(); - block2 - .transactions - .push(spend_transaction.into()); + block2.transactions.push(spend_transaction.into()); if use_finalized_state_spend { let block2 = FinalizedBlock::from(Arc::new(block2)); @@ -170,8 +181,7 @@ proptest! { prop_assert!(state.disk.utxo(&expected_outpoint).is_none()); } else { let block2 = Arc::new(block2).prepare(); - let commit_result = - state.validate_and_commit(block2.clone()); + let commit_result = state.validate_and_commit(block2.clone()); // the block was committed prop_assert_eq!(commit_result, Ok(())); @@ -182,19 +192,25 @@ proptest! { // the UTXO is spent prop_assert_eq!(state.mem.chain_set.len(), 1); - prop_assert!(!state.mem.chain_set.iter().next().unwrap().unspent_utxos().contains_key(&expected_outpoint)); + let chain = state + .mem + .chain_set + .iter() + .next() + .unwrap(); + prop_assert!(!chain.unspent_utxos().contains_key(&expected_outpoint)); if use_finalized_state_output { // the chain has spent the UTXO from the finalized state - prop_assert!(!state.mem.chain_set.iter().next().unwrap().created_utxos.contains_key(&expected_outpoint)); - prop_assert!(state.mem.chain_set.iter().next().unwrap().spent_utxos.contains(&expected_outpoint)); + prop_assert!(!chain.created_utxos.contains_key(&expected_outpoint)); + prop_assert!(chain.spent_utxos.contains(&expected_outpoint)); // the finalized state has the UTXO, but it will get deleted on commit prop_assert!(state.disk.utxo(&expected_outpoint).is_some()); } else { // the chain has spent its own UTXO - prop_assert!(!state.mem.chain_set.iter().next().unwrap().unspent_utxos().contains_key(&expected_outpoint)); - prop_assert!(state.mem.chain_set.iter().next().unwrap().created_utxos.contains_key(&expected_outpoint)); - prop_assert!(state.mem.chain_set.iter().next().unwrap().spent_utxos.contains(&expected_outpoint)); + prop_assert!(!chain.unspent_utxos().contains_key(&expected_outpoint)); + prop_assert!(chain.created_utxos.contains_key(&expected_outpoint)); + prop_assert!(chain.spent_utxos.contains(&expected_outpoint)); // the finalized state does not have the UTXO prop_assert!(state.disk.utxo(&expected_outpoint).is_none()); } @@ -218,11 +234,15 @@ proptest! { let output_transaction = transaction_v4_with_transparent_data([], [output.0]); - let expected_outpoint = transparent::OutPoint { hash: output_transaction.hash(), index: 0 }; + let expected_outpoint = transparent::OutPoint { + hash: output_transaction.hash(), + index: 0, + }; prevout_input1.set_outpoint(expected_outpoint); prevout_input2.set_outpoint(expected_outpoint); - let spend_transaction = transaction_v4_with_transparent_data([prevout_input1.0, prevout_input2.0], []); + let spend_transaction = + transaction_v4_with_transparent_data([prevout_input1.0, prevout_input2.0], []); // convert the coinbase transaction to a version that the non-finalized state will accept block1.transactions[0] = transaction_v4_from_coinbase(&block1.transactions[0]).into(); @@ -243,7 +263,8 @@ proptest! { Err(DuplicateTransparentSpend { outpoint: expected_outpoint, location: "the same block", - }.into()) + } + .into()) ); prop_assert_eq!(Some((Height(0), genesis.hash)), state.best_tip()); @@ -270,21 +291,25 @@ proptest! { .zcash_deserialize_into::() .expect("block should deserialize"); - let TestState { mut state, block1, .. } = new_state_with_mainnet_transparent_data([], [output.0], use_finalized_state_output); + let TestState { + mut state, block1, .. + } = new_state_with_mainnet_transparent_data([], [output.0], use_finalized_state_output); let previous_mem = state.mem.clone(); - let expected_outpoint = transparent::OutPoint { hash: block1.transactions[1].hash(), index: 0 }; + let expected_outpoint = transparent::OutPoint { + hash: block1.transactions[1].hash(), + index: 0, + }; prevout_input1.set_outpoint(expected_outpoint); prevout_input2.set_outpoint(expected_outpoint); - let spend_transaction = transaction_v4_with_transparent_data([prevout_input1.0, prevout_input2.0], []); + let spend_transaction = + transaction_v4_with_transparent_data([prevout_input1.0, prevout_input2.0], []); // convert the coinbase transaction to a version that the non-finalized state will accept block2.transactions[0] = transaction_v4_from_coinbase(&block2.transactions[0]).into(); - block2 - .transactions - .push(spend_transaction.into()); + block2.transactions.push(spend_transaction.into()); let block2 = Arc::new(block2).prepare(); let commit_result = state.validate_and_commit(block2); @@ -295,7 +320,8 @@ proptest! { Err(DuplicateTransparentSpend { outpoint: expected_outpoint, location: "the same block", - }.into()) + } + .into()) ); prop_assert_eq!(Some((Height(1), block1.hash())), state.best_tip()); @@ -308,8 +334,14 @@ proptest! { // the non-finalized state has no chains (so it can't have the UTXO) prop_assert!(state.mem.chain_set.iter().next().is_none()); } else { + let chain = state + .mem + .chain_set + .iter() + .next() + .unwrap(); // the non-finalized state has the UTXO - prop_assert!(state.mem.chain_set.iter().next().unwrap().unspent_utxos().contains_key(&expected_outpoint)); + prop_assert!(chain.unspent_utxos().contains_key(&expected_outpoint)); // the finalized state does not have the UTXO prop_assert!(state.disk.utxo(&expected_outpoint).is_none()); } @@ -332,10 +364,15 @@ proptest! { .zcash_deserialize_into::() .expect("block should deserialize"); - let TestState { mut state, block1, .. } = new_state_with_mainnet_transparent_data([], [output.0], use_finalized_state_output); + let TestState { + mut state, block1, .. + } = new_state_with_mainnet_transparent_data([], [output.0], use_finalized_state_output); let previous_mem = state.mem.clone(); - let expected_outpoint = transparent::OutPoint { hash: block1.transactions[1].hash(), index: 0 }; + let expected_outpoint = transparent::OutPoint { + hash: block1.transactions[1].hash(), + index: 0, + }; prevout_input1.set_outpoint(expected_outpoint); prevout_input2.set_outpoint(expected_outpoint); @@ -358,7 +395,8 @@ proptest! { Err(DuplicateTransparentSpend { outpoint: expected_outpoint, location: "the same block", - }.into()) + } + .into()) ); prop_assert_eq!(Some((Height(1), block1.hash())), state.best_tip()); @@ -371,8 +409,14 @@ proptest! { // the non-finalized state has no chains (so it can't have the UTXO) prop_assert!(state.mem.chain_set.iter().next().is_none()); } else { + let chain = state + .mem + .chain_set + .iter() + .next() + .unwrap(); // the non-finalized state has the UTXO - prop_assert!(state.mem.chain_set.iter().next().unwrap().unspent_utxos().contains_key(&expected_outpoint)); + prop_assert!(chain.unspent_utxos().contains_key(&expected_outpoint)); // the finalized state does not have the UTXO prop_assert!(state.disk.utxo(&expected_outpoint).is_none()); } @@ -405,10 +449,15 @@ proptest! { .zcash_deserialize_into::() .expect("block should deserialize"); - let TestState { mut state, block1, .. } = new_state_with_mainnet_transparent_data([], [output.0], use_finalized_state_output); + let TestState { + mut state, block1, .. + } = new_state_with_mainnet_transparent_data([], [output.0], use_finalized_state_output); let mut previous_mem = state.mem.clone(); - let expected_outpoint = transparent::OutPoint { hash: block1.transactions[1].hash(), index: 0 }; + let expected_outpoint = transparent::OutPoint { + hash: block1.transactions[1].hash(), + index: 0, + }; prevout_input1.set_outpoint(expected_outpoint); prevout_input2.set_outpoint(expected_outpoint); @@ -419,12 +468,8 @@ proptest! { block2.transactions[0] = transaction_v4_from_coinbase(&block2.transactions[0]).into(); block3.transactions[0] = transaction_v4_from_coinbase(&block3.transactions[0]).into(); - block2 - .transactions - .push(spend_transaction1.into()); - block3 - .transactions - .push(spend_transaction2.into()); + block2.transactions.push(spend_transaction1.into()); + block3.transactions.push(spend_transaction2.into()); let block2 = Arc::new(block2); @@ -455,45 +500,23 @@ proptest! { prop_assert!(!state.mem.eq_internal_state(&previous_mem)); prop_assert_eq!(state.mem.chain_set.len(), 1); + let chain = state + .mem + .chain_set + .iter() + .next() + .unwrap(); if use_finalized_state_output { // the finalized state has the unspent UTXO prop_assert!(state.disk.utxo(&expected_outpoint).is_some()); // the non-finalized state has spent the UTXO - prop_assert!(state - .mem - .chain_set - .iter() - .next() - .unwrap() - .spent_utxos - .contains(&expected_outpoint)); + prop_assert!(chain.spent_utxos.contains(&expected_outpoint)); } else { // the non-finalized state has created and spent the UTXO - prop_assert!(!state - .mem - .chain_set - .iter() - .next() - .unwrap() - .unspent_utxos() - .contains_key(&expected_outpoint)); - prop_assert!(state - .mem - .chain_set - .iter() - .next() - .unwrap() - .created_utxos - .contains_key(&expected_outpoint)); - prop_assert!(state - .mem - .chain_set - .iter() - .next() - .unwrap() - .spent_utxos - .contains(&expected_outpoint)); + prop_assert!(!chain.unspent_utxos().contains_key(&expected_outpoint)); + prop_assert!(chain.created_utxos.contains_key(&expected_outpoint)); + prop_assert!(chain.spent_utxos.contains(&expected_outpoint)); // the finalized state does not have the UTXO prop_assert!(state.disk.utxo(&expected_outpoint).is_none()); } @@ -511,7 +534,8 @@ proptest! { Err(MissingTransparentOutput { outpoint: expected_outpoint, location: "the non-finalized and finalized chain", - }.into()) + } + .into()) ); } else { prop_assert_eq!( @@ -519,7 +543,8 @@ proptest! { Err(DuplicateTransparentSpend { outpoint: expected_outpoint, location: "the non-finalized chain", - }.into()) + } + .into()) ); } prop_assert_eq!(Some((Height(2), block2.hash())), state.best_tip()); @@ -560,9 +585,7 @@ proptest! { // convert the coinbase transaction to a version that the non-finalized state will accept block1.transactions[0] = transaction_v4_from_coinbase(&block1.transactions[0]).into(); - block1 - .transactions - .push(spend_transaction.into()); + block1.transactions.push(spend_transaction.into()); let (mut state, genesis) = new_state_with_mainnet_genesis(); let previous_mem = state.mem.clone(); @@ -576,7 +599,8 @@ proptest! { Err(MissingTransparentOutput { outpoint: expected_outpoint, location: "the non-finalized and finalized chain", - }.into()) + } + .into()) ); prop_assert_eq!(Some((Height(0), genesis.hash)), state.best_tip()); @@ -607,7 +631,10 @@ proptest! { let output_transaction = transaction_v4_with_transparent_data([], [output.0]); // create a spend - let expected_outpoint = transparent::OutPoint { hash: output_transaction.hash(), index: 0 }; + let expected_outpoint = transparent::OutPoint { + hash: output_transaction.hash(), + index: 0, + }; prevout_input.set_outpoint(expected_outpoint); let spend_transaction = transaction_v4_with_transparent_data([prevout_input.0], []); @@ -630,7 +657,8 @@ proptest! { commit_result, Err(EarlyTransparentSpend { outpoint: expected_outpoint, - }.into()) + } + .into()) ); prop_assert_eq!(Some((Height(0), genesis.hash)), state.best_tip());