diff --git a/zcash_client_backend/src/data_api/testing.rs b/zcash_client_backend/src/data_api/testing.rs index fcc9452b1..9678dbd73 100644 --- a/zcash_client_backend/src/data_api/testing.rs +++ b/zcash_client_backend/src/data_api/testing.rs @@ -512,12 +512,12 @@ where compact_block.height(), prev_block.roll_forward(&compact_block), ); - self.cache.insert(&compact_block) + self.cache.insert(&compact_block).await } /// Creates a fake block at the expected next height containing a single output of the /// given value, and inserts it into the cache. - pub fn generate_next_block( + pub async fn generate_next_block( &mut self, fvk: &Fvk, address_type: AddressType, @@ -527,14 +527,16 @@ where let prior_cached_block = self.latest_cached_block().unwrap_or(&pre_activation_block); let height = prior_cached_block.height() + 1; - let (res, nfs) = self.generate_block_at( - height, - prior_cached_block.chain_state.block_hash(), - &[FakeCompactOutput::new(fvk, address_type, value)], - prior_cached_block.sapling_end_size, - prior_cached_block.orchard_end_size, - false, - ); + let (res, nfs) = self + .generate_block_at( + height, + prior_cached_block.chain_state.block_hash(), + &[FakeCompactOutput::new(fvk, address_type, value)], + prior_cached_block.sapling_end_size, + prior_cached_block.orchard_end_size, + false, + ) + .await; (height, res, nfs[0]) } @@ -542,7 +544,7 @@ where /// Creates a fake block at the expected next height containing multiple outputs /// and inserts it into the cache. #[allow(dead_code)] - pub fn generate_next_block_multi( + pub async fn generate_next_block_multi( &mut self, outputs: &[FakeCompactOutput], ) -> (BlockHeight, Cache::InsertResult, Vec) { @@ -550,21 +552,23 @@ where let prior_cached_block = self.latest_cached_block().unwrap_or(&pre_activation_block); let height = prior_cached_block.height() + 1; - let (res, nfs) = self.generate_block_at( - height, - prior_cached_block.chain_state.block_hash(), - outputs, - prior_cached_block.sapling_end_size, - prior_cached_block.orchard_end_size, - false, - ); + let (res, nfs) = self + .generate_block_at( + height, + prior_cached_block.chain_state.block_hash(), + outputs, + prior_cached_block.sapling_end_size, + prior_cached_block.orchard_end_size, + false, + ) + .await; (height, res, nfs) } /// Adds an empty block to the cache, advancing the simulated chain height. #[allow(dead_code)] // used only for tests that are flagged off by default - pub fn generate_empty_block(&mut self) -> (BlockHeight, Cache::InsertResult) { + pub async fn generate_empty_block(&mut self) -> (BlockHeight, Cache::InsertResult) { let new_hash = { let mut hash = vec![0; 32]; self.rng.fill_bytes(&mut hash); @@ -591,7 +595,7 @@ where orchard_commitment_tree_size: prior_cached_block.orchard_end_size, }); - let res = self.cache_block(&prior_cached_block, cb); + let res = self.cache_block(&prior_cached_block, cb).await; self.latest_block_height = Some(new_height); (new_height, res) @@ -603,7 +607,7 @@ where /// This generated block will be treated as the latest block, and subsequent calls to /// [`Self::generate_next_block`] will build on it. #[allow(clippy::too_many_arguments)] - pub fn generate_block_at( + pub async fn generate_block_at( &mut self, height: BlockHeight, prev_hash: BlockHash, @@ -676,7 +680,7 @@ where ); assert_eq!(cb.height(), height); - let res = self.cache_block(&prior_cached_block, cb); + let res = self.cache_block(&prior_cached_block, cb).await; self.latest_block_height = Some(height); (res, nfs) @@ -684,7 +688,7 @@ where /// Creates a fake block at the expected next height spending the given note, and /// inserts it into the cache. - pub fn generate_next_block_spending( + pub async fn generate_next_block_spending( &mut self, fvk: &Fvk, note: (Fvk::Nullifier, NonNegativeAmount), @@ -711,7 +715,7 @@ where ); assert_eq!(cb.height(), height); - let res = self.cache_block(&prior_cached_block, cb); + let res = self.cache_block(&prior_cached_block, cb).await; self.latest_block_height = Some(height); (height, res) @@ -722,7 +726,7 @@ where /// /// This generated block will be treated as the latest block, and subsequent calls to /// [`Self::generate_next_block`] (or similar) will build on it. - pub fn generate_next_block_including( + pub async fn generate_next_block_including( &mut self, txid: TxId, ) -> (BlockHeight, Cache::InsertResult) { @@ -735,7 +739,7 @@ where // Index 0 is by definition a coinbase transaction, and the wallet doesn't // construct coinbase transactions. So we pretend here that the block has a // coinbase transaction that does not have shielded coinbase outputs. - self.generate_next_block_from_tx(1, &tx) + self.generate_next_block_from_tx(1, &tx).await } /// Creates a fake block at the expected next height containing only the given @@ -743,7 +747,7 @@ where /// /// This generated block will be treated as the latest block, and subsequent calls to /// [`Self::generate_next_block`] will build on it. - pub fn generate_next_block_from_tx( + pub async fn generate_next_block_from_tx( &mut self, tx_index: usize, tx: &Transaction, @@ -765,7 +769,7 @@ where ); assert_eq!(cb.height(), height); - let res = self.cache_block(&prior_cached_block, cb); + let res = self.cache_block(&prior_cached_block, cb).await; self.latest_block_height = Some(height); (height, res) @@ -794,19 +798,24 @@ impl TestState where Cache: TestCache, ::Error: fmt::Debug, + ::Error: fmt::Debug, ParamsT: consensus::Parameters + Send + 'static, DbT: InputSource + WalletTest + WalletWrite + WalletCommitmentTrees, ::AccountId: ConditionallySelectable + Default + Send + 'static, { /// Invokes [`scan_cached_blocks`] with the given arguments, expecting success. - pub fn scan_cached_blocks(&mut self, from_height: BlockHeight, limit: usize) -> ScanSummary { - let result = self.try_scan_cached_blocks(from_height, limit); + pub async fn scan_cached_blocks( + &mut self, + from_height: BlockHeight, + limit: usize, + ) -> ScanSummary { + let result = self.try_scan_cached_blocks(from_height, limit).await; assert_matches!(result, Ok(_)); result.unwrap() } /// Invokes [`scan_cached_blocks`] with the given arguments. - pub fn try_scan_cached_blocks( + pub async fn try_scan_cached_blocks( &mut self, from_height: BlockHeight, limit: usize, @@ -814,7 +823,7 @@ where ScanSummary, super::chain::error::Error< ::Error, - ::Error, + ::Error, >, > { let prior_cached_block = self @@ -834,6 +843,7 @@ where &prior_cached_block.chain_state, &scan_range, ) + .await } /// Insert shard roots for both trees. diff --git a/zcash_client_backend/src/data_api/testing/pool.rs b/zcash_client_backend/src/data_api/testing/pool.rs index 846a68113..6aa91ef05 100644 --- a/zcash_client_backend/src/data_api/testing/pool.rs +++ b/zcash_client_backend/src/data_api/testing/pool.rs @@ -174,7 +174,7 @@ pub trait ShieldedPoolTester { /// - Builds the transaction. /// - Checks that the transaction was stored, and that the outputs are decryptable and /// have the expected details. -pub fn send_single_step_proposed_transfer( +pub async fn send_single_step_proposed_transfer( dsf: impl DataStoreFactory, cache: impl TestCache, ) { @@ -189,8 +189,10 @@ pub fn send_single_step_proposed_transfer( // Add funds to the wallet in a single note let value = Zatoshis::const_from_u64(60000); - let (h, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h, 1); + let (h, _, _) = st + .generate_next_block(&dfvk, AddressType::DefaultExternal, value) + .await; + st.scan_cached_blocks(h, 1).await; // Spendable balance matches total balance assert_eq!(st.get_total_balance(account.id()), value); @@ -316,7 +318,7 @@ pub fn send_single_step_proposed_transfer( ); } -pub fn send_with_multiple_change_outputs( +pub async fn send_with_multiple_change_outputs( dsf: impl DataStoreFactory, cache: impl TestCache, ) { @@ -331,8 +333,10 @@ pub fn send_with_multiple_change_outputs( // Add funds to the wallet in a single note let value = Zatoshis::const_from_u64(650_0000); - let (h, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h, 1); + let (h, _, _) = st + .generate_next_block(&dfvk, AddressType::DefaultExternal, value) + .await; + st.scan_cached_blocks(h, 1).await; // Spendable balance matches total balance assert_eq!(st.get_total_balance(account.id()), value); @@ -455,8 +459,8 @@ pub fn send_with_multiple_change_outputs( Ok(_) ); - let (h, _) = st.generate_next_block_including(sent_tx_id); - st.scan_cached_blocks(h, 1); + let (h, _) = st.generate_next_block_including(sent_tx_id).await; + st.scan_cached_blocks(h, 1).await; // Now, create another proposal with more outputs requested. We have two change notes; // we'll spend one of them, and then we'll generate 7 splits. @@ -486,7 +490,7 @@ pub fn send_with_multiple_change_outputs( } #[cfg(feature = "transparent-inputs")] -pub fn send_multi_step_proposed_transfer( +pub async fn send_multi_step_proposed_transfer( ds_factory: DSF, cache: impl TestCache, is_reached_gap_limit: impl Fn(&::Error, DSF::AccountId, u32) -> bool, @@ -494,7 +498,11 @@ pub fn send_multi_step_proposed_transfer( DSF: DataStoreFactory, ::AccountId: std::fmt::Debug, { - use crate::data_api::{OutputOfSentTx, GAP_LIMIT}; + use std::fmt; + + use zcash_primitives::transaction::TxId; + + use crate::data_api::{testing::TestAccount, OutputOfSentTx, GAP_LIMIT}; let mut st = TestBuilder::new() .with_data_store_factory(ds_factory) @@ -507,9 +515,21 @@ pub fn send_multi_step_proposed_transfer( let (default_addr, default_index) = account.usk().default_transparent_address(); let dfvk = T::test_account_fvk(&st); - let add_funds = |st: &mut TestState<_, DSF::DataStore, _>, value| { - let (h, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h, 1); + async fn add_funds( + st: &mut TestState, + value: NonNegativeAmount, + dfvk: &::Fvk, + account_id: DSF::AccountId, + ) -> BlockHeight + where + C: TestCache, + DSF: DataStoreFactory, + P: Parameters + Send + 'static, + { + let (h, _, _) = st + .generate_next_block(&dfvk, AddressType::DefaultExternal, value) + .await; + st.scan_cached_blocks(h, 1).await; assert_eq!( st.wallet() @@ -521,14 +541,31 @@ pub fn send_multi_step_proposed_transfer( ); assert_eq!(st.get_spendable_balance(account_id, 1), value); h - }; + } let value = NonNegativeAmount::const_from_u64(100000); let transfer_amount = NonNegativeAmount::const_from_u64(50000); - let run_test = |st: &mut TestState<_, DSF::DataStore, _>, expected_index| { + #[allow(clippy::too_many_arguments)] + async fn run_test( + st: &mut TestState, + expected_index: u32, + value: NonNegativeAmount, + transfer_amount: NonNegativeAmount, + default_addr: TransparentAddress, + account: &TestAccount, + dfvk: &::Fvk, + ) -> (Address, NonEmpty) + where + C: TestCache, + DSF: DataStoreFactory, + DSF::AccountId: fmt::Debug, + P: Parameters + Send + 'static, + { + let account_id = account.id(); + // Add funds to the wallet. - add_funds(st, value); + add_funds::(st, value, dfvk, account_id).await; let expected_step0_fee = (zip317::MARGINAL_FEE * 3).unwrap(); let expected_step1_fee = zip317::MINIMUM_FEE; @@ -646,14 +683,32 @@ pub fn send_multi_step_proposed_transfer( ); (ephemeral_address.unwrap().0, txids) - }; + } // Each transfer should use a different ephemeral address. - let (ephemeral0, txids0) = run_test(&mut st, 0); - let (ephemeral1, txids1) = run_test(&mut st, 1); + let (ephemeral0, txids0) = run_test::( + &mut st, + 0, + value, + transfer_amount, + default_addr, + &account, + &dfvk, + ) + .await; + let (ephemeral1, txids1) = run_test::( + &mut st, + 1, + value, + transfer_amount, + default_addr, + &account, + &dfvk, + ) + .await; assert_ne!(ephemeral0, ephemeral1); - let height = add_funds(&mut st, value); + let height = add_funds::(&mut st, value, &dfvk, account_id).await; assert_matches!( ephemeral0, @@ -820,22 +875,22 @@ pub fn send_multi_step_proposed_transfer( // We already reserved 20 addresses, so this should allow 2 more (..22). // It does not matter that the transaction with ephemeral output at index 0 // remains unmined. - let (h, _) = st.generate_next_block_including(txids1.head); - st.scan_cached_blocks(h, 1); + let (h, _) = st.generate_next_block_including(txids1.head).await; + st.scan_cached_blocks(h, 1).await; reservation_should_succeed(&mut st, 2); reservation_should_fail(&mut st, 1, 22); // Mining the transaction with the ephemeral output at index 0 at this point // should make no difference. - let (h, _) = st.generate_next_block_including(txids0.head); - st.scan_cached_blocks(h, 1); + let (h, _) = st.generate_next_block_including(txids0.head).await; + st.scan_cached_blocks(h, 1).await; reservation_should_fail(&mut st, 1, 22); // Now mine the transaction with the ephemeral output at index 10. let tx = build_result.transaction(); let tx_index = 1; - let (h, _) = st.generate_next_block_from_tx(tx_index, tx); - st.scan_cached_blocks(h, 1); + let (h, _) = st.generate_next_block_from_tx(tx_index, tx).await; + st.scan_cached_blocks(h, 1).await; // The above `scan_cached_blocks` does not detect `tx` as interesting to the // wallet. If a transaction is in the database with a null `mined_height`, @@ -873,7 +928,7 @@ pub fn send_multi_step_proposed_transfer( } #[cfg(feature = "transparent-inputs")] -pub fn proposal_fails_if_not_all_ephemeral_outputs_consumed( +pub async fn proposal_fails_if_not_all_ephemeral_outputs_consumed( ds_factory: DSF, cache: impl TestCache, ) where @@ -889,9 +944,20 @@ pub fn proposal_fails_if_not_all_ephemeral_outputs_consumed, value| { - let (h, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h, 1); + async fn add_funds( + st: &mut TestState, + value: NonNegativeAmount, + dfvk: &::Fvk, + account_id: DSF::AccountId, + ) where + C: TestCache, + DSF: DataStoreFactory, + P: Parameters + Send + 'static, + { + let (h, _, _) = st + .generate_next_block(&dfvk, AddressType::DefaultExternal, value) + .await; + st.scan_cached_blocks(h, 1).await; assert_eq!( st.wallet() @@ -902,13 +968,13 @@ pub fn proposal_fails_if_not_all_ephemeral_outputs_consumed(&mut st, value, &dfvk, account_id).await; // Generate a ZIP 320 proposal, sending to the wallet's default transparent address // expressed as a TEX address. @@ -1032,7 +1098,7 @@ where ); } -pub fn spend_fails_on_unverified_notes( +pub async fn spend_fails_on_unverified_notes( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { @@ -1048,8 +1114,10 @@ pub fn spend_fails_on_unverified_notes( // Add funds to the wallet in a single note let value = NonNegativeAmount::const_from_u64(50000); - let (h1, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h1, 1); + let (h1, _, _) = st + .generate_next_block(&dfvk, AddressType::DefaultExternal, value) + .await; + st.scan_cached_blocks(h1, 1).await; // Spendable balance matches total balance at 1 confirmation. assert_eq!(st.get_total_balance(account_id), value); @@ -1076,8 +1144,10 @@ pub fn spend_fails_on_unverified_notes( assert_eq!(summary.map(|s| s.progress().scan()), Some(Ratio::new(1, 1))); // Add more funds to the wallet in a second note - let (h2, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h2, 1); + let (h2, _, _) = st + .generate_next_block(&dfvk, AddressType::DefaultExternal, value) + .await; + st.scan_cached_blocks(h2, 1).await; // Verified balance does not include the second note let total = (value + value).unwrap(); @@ -1118,9 +1188,10 @@ pub fn spend_fails_on_unverified_notes( // Mine blocks SAPLING_ACTIVATION_HEIGHT + 2 to 9 until just before the second // note is verified for _ in 2..10 { - st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); + st.generate_next_block(&dfvk, AddressType::DefaultExternal, value) + .await; } - st.scan_cached_blocks(h2 + 1, 8); + st.scan_cached_blocks(h2 + 1, 8).await; // Total balance is value * number of blocks scanned (10). assert_eq!(st.get_total_balance(account_id), (value * 10).unwrap()); @@ -1146,8 +1217,10 @@ pub fn spend_fails_on_unverified_notes( ); // Mine block 11 so that the second note becomes verified - let (h11, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h11, 1); + let (h11, _, _) = st + .generate_next_block(&dfvk, AddressType::DefaultExternal, value) + .await; + st.scan_cached_blocks(h11, 1).await; // Total balance is value * number of blocks scanned (11). assert_eq!(st.get_total_balance(account_id), (value * 11).unwrap()); @@ -1186,8 +1259,8 @@ pub fn spend_fails_on_unverified_notes( ) .unwrap()[0]; - let (h, _) = st.generate_next_block_including(txid); - st.scan_cached_blocks(h, 1); + let (h, _) = st.generate_next_block_including(txid).await; + st.scan_cached_blocks(h, 1).await; // TODO: send to an account so that we can check its balance. assert_eq!( @@ -1198,7 +1271,7 @@ pub fn spend_fails_on_unverified_notes( ); } -pub fn spend_fails_on_locked_notes( +pub async fn spend_fails_on_locked_notes( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { @@ -1216,8 +1289,10 @@ pub fn spend_fails_on_locked_notes( // Add funds to the wallet in a single note let value = NonNegativeAmount::const_from_u64(50000); - let (h1, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h1, 1); + let (h1, _, _) = st + .generate_next_block(&dfvk, AddressType::DefaultExternal, value) + .await; + st.scan_cached_blocks(h1, 1).await; // Spendable balance matches total balance at 1 confirmation. assert_eq!(st.get_total_balance(account_id), value); @@ -1272,9 +1347,10 @@ pub fn spend_fails_on_locked_notes( &T::sk_to_fvk(&T::sk(&[i as u8; 32])), AddressType::DefaultExternal, value, - ); + ) + .await; } - st.scan_cached_blocks(h1 + 1, 40); + st.scan_cached_blocks(h1 + 1, 40).await; // Second proposal still fails assert_matches!( @@ -1296,12 +1372,14 @@ pub fn spend_fails_on_locked_notes( ); // Mine block SAPLING_ACTIVATION_HEIGHT + 42 so that the first transaction expires - let (h43, _, _) = st.generate_next_block( - &T::sk_to_fvk(&T::sk(&[42; 32])), - AddressType::DefaultExternal, - value, - ); - st.scan_cached_blocks(h43, 1); + let (h43, _, _) = st + .generate_next_block( + &T::sk_to_fvk(&T::sk(&[42; 32])), + AddressType::DefaultExternal, + value, + ) + .await; + st.scan_cached_blocks(h43, 1).await; // Spendable balance matches total balance at 1 confirmation. assert_eq!(st.get_total_balance(account_id), value); @@ -1331,8 +1409,8 @@ pub fn spend_fails_on_locked_notes( ) .unwrap()[0]; - let (h, _) = st.generate_next_block_including(txid2); - st.scan_cached_blocks(h, 1); + let (h, _) = st.generate_next_block_including(txid2).await; + st.scan_cached_blocks(h, 1).await; // TODO: send to an account so that we can check its balance. assert_eq!( @@ -1341,7 +1419,7 @@ pub fn spend_fails_on_locked_notes( ); } -pub fn ovk_policy_prevents_recovery_from_chain( +pub async fn ovk_policy_prevents_recovery_from_chain( ds_factory: DSF, cache: impl TestCache, ) where @@ -1359,8 +1437,10 @@ pub fn ovk_policy_prevents_recovery_from_chain( // Add funds to the wallet in a single note let value = NonNegativeAmount::const_from_u64(50000); - let (h1, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h1, 1); + let (h1, _, _) = st + .generate_next_block(&dfvk, AddressType::DefaultExternal, value) + .await; + st.scan_cached_blocks(h1, 1).await; // Spendable balance matches total balance at 1 confirmation. assert_eq!(st.get_total_balance(account_id), value); @@ -1421,9 +1501,10 @@ pub fn ovk_policy_prevents_recovery_from_chain( &T::sk_to_fvk(&T::sk(&[i as u8; 32])), AddressType::DefaultExternal, value, - ); + ) + .await; } - st.scan_cached_blocks(h1 + 1, 42); + st.scan_cached_blocks(h1 + 1, 42).await; // Send the funds again, discarding history. // Neither transaction output is decryptable by the sender. @@ -1433,7 +1514,7 @@ pub fn ovk_policy_prevents_recovery_from_chain( ); } -pub fn spend_succeeds_to_t_addr_zero_change( +pub async fn spend_succeeds_to_t_addr_zero_change( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { @@ -1449,8 +1530,10 @@ pub fn spend_succeeds_to_t_addr_zero_change( // Add funds to the wallet in a single note let value = NonNegativeAmount::const_from_u64(70000); - let (h, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h, 1); + let (h, _, _) = st + .generate_next_block(&dfvk, AddressType::DefaultExternal, value) + .await; + st.scan_cached_blocks(h, 1).await; // Spendable balance matches total balance at 1 confirmation. assert_eq!(st.get_total_balance(account_id), value); @@ -1481,7 +1564,7 @@ pub fn spend_succeeds_to_t_addr_zero_change( ); } -pub fn change_note_spends_succeed( +pub async fn change_note_spends_succeed( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { @@ -1497,8 +1580,10 @@ pub fn change_note_spends_succeed( // Add funds to the wallet in a single note owned by the internal spending key let value = NonNegativeAmount::const_from_u64(70000); - let (h, _, _) = st.generate_next_block(&dfvk, AddressType::Internal, value); - st.scan_cached_blocks(h, 1); + let (h, _, _) = st + .generate_next_block(&dfvk, AddressType::Internal, value) + .await; + st.scan_cached_blocks(h, 1).await; // Spendable balance matches total balance at 1 confirmation. assert_eq!(st.get_total_balance(account_id), value); @@ -1544,7 +1629,10 @@ pub fn change_note_spends_succeed( ); } -pub fn external_address_change_spends_detected_in_restore_from_seed( +pub async fn external_address_change_spends_detected_in_restore_from_seed< + T: ShieldedPoolTester, + DSF, +>( ds_factory: DSF, cache: impl TestCache, ) where @@ -1567,8 +1655,10 @@ pub fn external_address_change_spends_detected_in_restore_from_seed( +pub async fn zip317_spend( ds_factory: DSF, cache: impl TestCache, ) { @@ -1657,11 +1748,13 @@ pub fn zip317_spend( let dfvk = T::test_account_fvk(&st); // Add funds to the wallet - let (h1, _, _) = st.generate_next_block( - &dfvk, - AddressType::Internal, - NonNegativeAmount::const_from_u64(50000), - ); + let (h1, _, _) = st + .generate_next_block( + &dfvk, + AddressType::Internal, + NonNegativeAmount::const_from_u64(50000), + ) + .await; // Add 10 dust notes to the wallet for _ in 1..=10 { @@ -1669,10 +1762,11 @@ pub fn zip317_spend( &dfvk, AddressType::DefaultExternal, NonNegativeAmount::const_from_u64(1000), - ); + ) + .await; } - st.scan_cached_blocks(h1, 11); + st.scan_cached_blocks(h1, 11).await; // Spendable balance matches total balance let total = NonNegativeAmount::const_from_u64(60000); @@ -1723,8 +1817,8 @@ pub fn zip317_spend( ) .unwrap()[0]; - let (h, _) = st.generate_next_block_including(txid); - st.scan_cached_blocks(h, 1); + let (h, _) = st.generate_next_block_including(txid).await; + st.scan_cached_blocks(h, 1).await; // TODO: send to an account so that we can check its balance. // We sent back to the same account so the amount_sent should be included @@ -1736,7 +1830,7 @@ pub fn zip317_spend( } #[cfg(feature = "transparent-inputs")] -pub fn shield_transparent(ds_factory: DSF, cache: impl TestCache) +pub async fn shield_transparent(ds_factory: DSF, cache: impl TestCache) where DSF: DataStoreFactory, <::DataStore as WalletWrite>::UtxoRef: std::fmt::Debug, @@ -1758,12 +1852,14 @@ where let taddr = uaddr.transparent().unwrap(); // Ensure that the wallet has at least one block - let (h, _, _) = st.generate_next_block( - &dfvk, - AddressType::Internal, - NonNegativeAmount::const_from_u64(50000), - ); - st.scan_cached_blocks(h, 1); + let (h, _, _) = st + .generate_next_block( + &dfvk, + AddressType::Internal, + NonNegativeAmount::const_from_u64(50000), + ) + .await; + st.scan_cached_blocks(h, 1).await; let utxo = WalletTransparentOutput::from_parts( OutPoint::fake(), @@ -1803,7 +1899,7 @@ where assert!(tx.is_shielding()); // Generate and scan the block including the transaction - let (h, _) = st.generate_next_block_including(*txids.first()); + let (h, _) = st.generate_next_block_including(*txids.first()).await; st.scan_cached_blocks(h, 1); // Ensure that the transaction metadata is still correct after the update produced by scanning. @@ -1817,7 +1913,7 @@ where // FIXME: This requires fixes to the test framework. #[allow(dead_code)] -pub fn birthday_in_anchor_shard( +pub async fn birthday_in_anchor_shard( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { @@ -1882,27 +1978,32 @@ pub fn birthday_in_anchor_shard( // Generate 9 blocks that have no value for us, starting at the birthday height. let not_our_value = NonNegativeAmount::const_from_u64(10000); let not_our_key = T::random_fvk(st.rng_mut()); - let (initial_height, _, _) = - st.generate_next_block(¬_our_key, AddressType::DefaultExternal, not_our_value); + let (initial_height, _, _) = st + .generate_next_block(¬_our_key, AddressType::DefaultExternal, not_our_value) + .await; for _ in 1..9 { - st.generate_next_block(¬_our_key, AddressType::DefaultExternal, not_our_value); + st.generate_next_block(¬_our_key, AddressType::DefaultExternal, not_our_value) + .await; } // Now, generate a block that belongs to our wallet - let (received_tx_height, _, _) = st.generate_next_block( - &T::test_account_fvk(&st), - AddressType::DefaultExternal, - NonNegativeAmount::const_from_u64(500000), - ); + let (received_tx_height, _, _) = st + .generate_next_block( + &T::test_account_fvk(&st), + AddressType::DefaultExternal, + NonNegativeAmount::const_from_u64(500000), + ) + .await; // Generate some more blocks to get above our anchor height for _ in 0..15 { - st.generate_next_block(¬_our_key, AddressType::DefaultExternal, not_our_value); + st.generate_next_block(¬_our_key, AddressType::DefaultExternal, not_our_value) + .await; } // Scan a block range that includes our received note, but skips some blocks we need to // make it spendable. - st.scan_cached_blocks(initial_height + 5, 20); + st.scan_cached_blocks(initial_height + 5, 20).await; // Verify that the received note is not considered spendable let account = st.test_account().unwrap(); @@ -1919,7 +2020,7 @@ pub fn birthday_in_anchor_shard( assert_eq!(spendable.len(), 0); // Scan the blocks we skipped - st.scan_cached_blocks(initial_height, 5); + st.scan_cached_blocks(initial_height, 5).await; // Verify that the received note is now considered spendable let spendable = T::select_spendable_notes( @@ -1934,7 +2035,7 @@ pub fn birthday_in_anchor_shard( assert_eq!(spendable.len(), 1); } -pub fn checkpoint_gaps( +pub async fn checkpoint_gaps( ds_factory: DSF, cache: impl TestCache, ) { @@ -1952,8 +2053,9 @@ pub fn checkpoint_gaps( &dfvk, AddressType::DefaultExternal, NonNegativeAmount::const_from_u64(500000), - ); - st.scan_cached_blocks(account.birthday().height(), 1); + ) + .await; + st.scan_cached_blocks(account.birthday().height(), 1).await; // Create a gap of 10 blocks having no shielded outputs, then add a block that doesn't // belong to us so that we can get a checkpoint in the tree. @@ -1970,10 +2072,12 @@ pub fn checkpoint_gaps( st.latest_cached_block().unwrap().sapling_end_size(), st.latest_cached_block().unwrap().orchard_end_size(), false, - ); + ) + .await; // Scan the block - st.scan_cached_blocks(account.birthday().height() + 10, 1); + st.scan_cached_blocks(account.birthday().height() + 10, 1) + .await; // Verify that our note is considered spendable let spendable = T::select_spendable_notes( @@ -2012,7 +2116,7 @@ pub fn checkpoint_gaps( } #[cfg(feature = "orchard")] -pub fn pool_crossing_required( +pub async fn pool_crossing_required( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { @@ -2031,8 +2135,9 @@ pub fn pool_crossing_required( let p1_to = P1::fvk_default_address(&p1_fvk); let note_value = NonNegativeAmount::const_from_u64(350000); - st.generate_next_block(&p0_fvk, AddressType::DefaultExternal, note_value); - st.scan_cached_blocks(account.birthday().height(), 2); + st.generate_next_block(&p0_fvk, AddressType::DefaultExternal, note_value) + .await; + st.scan_cached_blocks(account.birthday().height(), 2).await; let initial_balance = note_value; assert_eq!(st.get_total_balance(account.id()), initial_balance); @@ -2087,8 +2192,10 @@ pub fn pool_crossing_required( ); assert_matches!(&create_proposed_result, Ok(txids) if txids.len() == 1); - let (h, _) = st.generate_next_block_including(create_proposed_result.unwrap()[0]); - st.scan_cached_blocks(h, 1); + let (h, _) = st + .generate_next_block_including(create_proposed_result.unwrap()[0]) + .await; + st.scan_cached_blocks(h, 1).await; assert_eq!( st.get_total_balance(account.id()), @@ -2101,7 +2208,7 @@ pub fn pool_crossing_required( } #[cfg(feature = "orchard")] -pub fn fully_funded_fully_private( +pub async fn fully_funded_fully_private( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { @@ -2120,9 +2227,11 @@ pub fn fully_funded_fully_private( +pub async fn fully_funded_send_to_t( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { @@ -2210,9 +2321,11 @@ pub fn fully_funded_send_to_t( let (p1_to, _) = account.usk().default_transparent_address(); let note_value = NonNegativeAmount::const_from_u64(350000); - st.generate_next_block(&p0_fvk, AddressType::DefaultExternal, note_value); - st.generate_next_block(&p1_fvk, AddressType::DefaultExternal, note_value); - st.scan_cached_blocks(account.birthday().height(), 2); + st.generate_next_block(&p0_fvk, AddressType::DefaultExternal, note_value) + .await; + st.generate_next_block(&p1_fvk, AddressType::DefaultExternal, note_value) + .await; + st.scan_cached_blocks(account.birthday().height(), 2).await; let initial_balance = (note_value * 2).unwrap(); assert_eq!(st.get_total_balance(account.id()), initial_balance); @@ -2265,8 +2378,10 @@ pub fn fully_funded_send_to_t( ); assert_matches!(&create_proposed_result, Ok(txids) if txids.len() == 1); - let (h, _) = st.generate_next_block_including(create_proposed_result.unwrap()[0]); - st.scan_cached_blocks(h, 1); + let (h, _) = st + .generate_next_block_including(create_proposed_result.unwrap()[0]) + .await; + st.scan_cached_blocks(h, 1).await; assert_eq!( st.get_total_balance(account.id()), @@ -2279,7 +2394,7 @@ pub fn fully_funded_send_to_t( } #[cfg(feature = "orchard")] -pub fn multi_pool_checkpoint( +pub async fn multi_pool_checkpoint( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { @@ -2299,11 +2414,14 @@ pub fn multi_pool_checkpoint( // Add some funds to the wallet; we add two notes to allow successive spends. Also, // we will generate a note in the P1 pool to ensure that we have some tree state. let note_value = NonNegativeAmount::const_from_u64(500000); - let (start_height, _, _) = - st.generate_next_block(&p0_fvk, AddressType::DefaultExternal, note_value); - st.generate_next_block(&p0_fvk, AddressType::DefaultExternal, note_value); - st.generate_next_block(&p1_fvk, AddressType::DefaultExternal, note_value); - let scanned = st.scan_cached_blocks(start_height, 3); + let (start_height, _, _) = st + .generate_next_block(&p0_fvk, AddressType::DefaultExternal, note_value) + .await; + st.generate_next_block(&p0_fvk, AddressType::DefaultExternal, note_value) + .await; + st.generate_next_block(&p1_fvk, AddressType::DefaultExternal, note_value) + .await; + let scanned = st.scan_cached_blocks(start_height, 3).await; let next_to_scan = scanned.scanned_range().end; @@ -2313,11 +2431,11 @@ pub fn multi_pool_checkpoint( // Generate several empty blocks for _ in 0..10 { - st.generate_empty_block(); + st.generate_empty_block().await; } // Scan into the middle of the empty range - let scanned = st.scan_cached_blocks(next_to_scan, 5); + let scanned = st.scan_cached_blocks(next_to_scan, 5).await; let next_to_scan = scanned.scanned_range().end; // The initial balance should be unchanged. @@ -2346,7 +2464,7 @@ pub fn multi_pool_checkpoint( NonZeroU32::new(1).unwrap(), ) .unwrap(); - st.generate_next_block_including(*res.first()); + st.generate_next_block_including(*res.first()).await; let expected_fee = NonNegativeAmount::const_from_u64(10000); let expected_change = (note_value - transfer_amount - expected_fee).unwrap(); @@ -2378,22 +2496,24 @@ pub fn multi_pool_checkpoint( NonZeroU32::new(1).unwrap(), ) .unwrap(); - st.generate_next_block_including(*res.first()); + st.generate_next_block_including(*res.first()).await; // Generate a few more empty blocks for _ in 0..5 { - st.generate_empty_block(); + st.generate_empty_block().await; } // Generate another block with funds for us - let (max_height, _, _) = - st.generate_next_block(&p0_fvk, AddressType::DefaultExternal, note_value); + let (max_height, _, _) = st + .generate_next_block(&p0_fvk, AddressType::DefaultExternal, note_value) + .await; // Scan everything. st.scan_cached_blocks( next_to_scan, usize::try_from(u32::from(max_height) - u32::from(next_to_scan) + 1).unwrap(), - ); + ) + .await; let expected_final = (initial_balance + note_value - (transfer_amount * 3).unwrap() @@ -2443,7 +2563,7 @@ pub fn multi_pool_checkpoint( } #[cfg(feature = "orchard")] -pub fn multi_pool_checkpoints_with_pruning( +pub async fn multi_pool_checkpoints_with_pruning( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { @@ -2463,21 +2583,27 @@ pub fn multi_pool_checkpoints_with_pruning( +pub async fn valid_chain_states( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { @@ -2493,29 +2619,33 @@ pub fn valid_chain_states( assert_matches!(st.wallet().chain_height(), Ok(None)); // Create a fake CompactBlock sending value to the address - let (h1, _, _) = st.generate_next_block( - &dfvk, - AddressType::DefaultExternal, - NonNegativeAmount::const_from_u64(5), - ); + let (h1, _, _) = st + .generate_next_block( + &dfvk, + AddressType::DefaultExternal, + NonNegativeAmount::const_from_u64(5), + ) + .await; // Scan the cache - st.scan_cached_blocks(h1, 1); + st.scan_cached_blocks(h1, 1).await; // Create a second fake CompactBlock sending more value to the address - let (h2, _, _) = st.generate_next_block( - &dfvk, - AddressType::DefaultExternal, - NonNegativeAmount::const_from_u64(7), - ); + let (h2, _, _) = st + .generate_next_block( + &dfvk, + AddressType::DefaultExternal, + NonNegativeAmount::const_from_u64(7), + ) + .await; // Scanning should detect no inconsistencies - st.scan_cached_blocks(h2, 1); + st.scan_cached_blocks(h2, 1).await; } // FIXME: This requires fixes to the test framework. #[allow(dead_code)] -pub fn invalid_chain_cache_disconnected( +pub async fn invalid_chain_cache_disconnected( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { @@ -2528,19 +2658,23 @@ pub fn invalid_chain_cache_disconnected( let dfvk = T::test_account_fvk(&st); // Create some fake CompactBlocks - let (h, _, _) = st.generate_next_block( - &dfvk, - AddressType::DefaultExternal, - NonNegativeAmount::const_from_u64(5), - ); - let (last_contiguous_height, _, _) = st.generate_next_block( - &dfvk, - AddressType::DefaultExternal, - NonNegativeAmount::const_from_u64(7), - ); + let (h, _, _) = st + .generate_next_block( + &dfvk, + AddressType::DefaultExternal, + NonNegativeAmount::const_from_u64(5), + ) + .await; + let (last_contiguous_height, _, _) = st + .generate_next_block( + &dfvk, + AddressType::DefaultExternal, + NonNegativeAmount::const_from_u64(7), + ) + .await; // Scanning the cache should find no inconsistencies - st.scan_cached_blocks(h, 2); + st.scan_cached_blocks(h, 2).await; // Create more fake CompactBlocks that don't connect to the scanned ones let disconnect_height = last_contiguous_height + 1; @@ -2555,25 +2689,27 @@ pub fn invalid_chain_cache_disconnected( 2, 2, true, - ); + ) + .await; st.generate_next_block( &dfvk, AddressType::DefaultExternal, NonNegativeAmount::const_from_u64(3), - ); + ) + .await; // Data+cache chain should be invalid at the data/cache boundary assert_matches!( st.try_scan_cached_blocks( disconnect_height, 2 - ), + ).await, Err(chain::error::Error::Scan(ScanError::PrevHashMismatch { at_height })) if at_height == disconnect_height ); } -pub fn data_db_truncation(ds_factory: DSF, cache: impl TestCache) +pub async fn data_db_truncation(ds_factory: DSF, cache: impl TestCache) where DSF: DataStoreFactory, ::AccountId: std::fmt::Debug, @@ -2593,11 +2729,14 @@ where // Create fake CompactBlocks sending value to the address let value = NonNegativeAmount::const_from_u64(5); let value2 = NonNegativeAmount::const_from_u64(7); - let (h, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.generate_next_block(&dfvk, AddressType::DefaultExternal, value2); + let (h, _, _) = st + .generate_next_block(&dfvk, AddressType::DefaultExternal, value) + .await; + st.generate_next_block(&dfvk, AddressType::DefaultExternal, value2) + .await; // Scan the cache - st.scan_cached_blocks(h, 2); + st.scan_cached_blocks(h, 2).await; // Spendable balance should reflect both received notes assert_eq!( @@ -2623,7 +2762,7 @@ where assert_eq!(st.get_pending_shielded_balance(account.id(), 1), value2); // Scan the cache again - st.scan_cached_blocks(h, 2); + st.scan_cached_blocks(h, 2).await; // Account balance should again reflect both received notes assert_eq!( @@ -2632,7 +2771,7 @@ where ); } -pub fn reorg_to_checkpoint(ds_factory: DSF, cache: C) +pub async fn reorg_to_checkpoint(ds_factory: DSF, cache: C) where DSF: DataStoreFactory, ::AccountId: std::fmt::Debug, @@ -2648,19 +2787,27 @@ where // Create a sequence of blocks to serve as the foundation of our chain state. let p0_fvk = T::random_fvk(st.rng_mut()); - let gen_random_block = |st: &mut TestState, - output_count: usize| { + async fn gen_random_block( + st: &mut TestState, + output_count: usize, + p0_fvk: &T::Fvk, + ) -> usize + where + T: ShieldedPoolTester, + DSF: DataStoreFactory, + C: TestCache, + { let fake_outputs = std::iter::repeat_with(|| FakeCompactOutput::random(st.rng_mut(), p0_fvk.clone())) .take(output_count) .collect::>(); - st.generate_next_block_multi(&fake_outputs[..]); + st.generate_next_block_multi(&fake_outputs[..]).await; output_count - }; + } // The stable portion of the tree will contain 20 notes. for _ in 0..10 { - gen_random_block(&mut st, 4); + gen_random_block::(&mut st, 4, &p0_fvk).await; } // We will reorg to this height. @@ -2669,7 +2816,7 @@ where // Scan the first 5 blocks. The last block in this sequence will be where we simulate a // reorg. - st.scan_cached_blocks(account.birthday().height(), 5); + st.scan_cached_blocks(account.birthday().height(), 5).await; assert_eq!( st.wallet() .block_max_scanned() @@ -2692,7 +2839,7 @@ where ); // Scan another block, then simulate a reorg. - st.scan_cached_blocks(reorg_height + 1, 1); + st.scan_cached_blocks(reorg_height + 1, 1).await; assert_eq!( st.wallet() .block_max_scanned() @@ -2736,7 +2883,7 @@ where ); // Skip two blocks, then (re) scan the same block. - st.scan_cached_blocks(reorg_height + 2, 1); + st.scan_cached_blocks(reorg_height + 2, 1).await; // Given the buggy truncation, this would result in this the following tree state: // /\ /\ \ /\ @@ -2762,17 +2909,17 @@ where // Generate some new random blocks for _ in 0..10 { let output_count = st.rng_mut().gen_range(2..10); - gen_random_block(&mut st, output_count); + gen_random_block::(&mut st, output_count, &p0_fvk).await; } // The previous truncation retained the cache, so re-scanning the same blocks would have // resulted in the same note commitment tree state, and hence no conflicts; could occur. Now // that we have cleared the cache and generated a different sequence blocks, if truncation did // not completely clear the tree state this would generates a note commitment tree conflict. - st.scan_cached_blocks(reorg_height + 1, 1); + st.scan_cached_blocks(reorg_height + 1, 1).await; } -pub fn scan_cached_blocks_allows_blocks_out_of_order( +pub async fn scan_cached_blocks_allows_blocks_out_of_order( ds_factory: impl DataStoreFactory, cache: impl TestCache, ) { @@ -2786,19 +2933,25 @@ pub fn scan_cached_blocks_allows_blocks_out_of_order( let dfvk = T::test_account_fvk(&st); let value = NonNegativeAmount::const_from_u64(50000); - let (h1, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - st.scan_cached_blocks(h1, 1); + let (h1, _, _) = st + .generate_next_block(&dfvk, AddressType::DefaultExternal, value) + .await; + st.scan_cached_blocks(h1, 1).await; assert_eq!(st.get_total_balance(account.id()), value); // Create blocks to reach height + 2 - let (h2, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); - let (h3, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); + let (h2, _, _) = st + .generate_next_block(&dfvk, AddressType::DefaultExternal, value) + .await; + let (h3, _, _) = st + .generate_next_block(&dfvk, AddressType::DefaultExternal, value) + .await; // Scan the later block first - st.scan_cached_blocks(h3, 1); + st.scan_cached_blocks(h3, 1).await; // Now scan the block of height height + 1 - st.scan_cached_blocks(h2, 1); + st.scan_cached_blocks(h2, 1).await; assert_eq!( st.get_total_balance(account.id()), NonNegativeAmount::const_from_u64(150_000) @@ -2828,7 +2981,7 @@ pub fn scan_cached_blocks_allows_blocks_out_of_order( ); } -pub fn scan_cached_blocks_finds_received_notes( +pub async fn scan_cached_blocks_finds_received_notes( ds_factory: DSF, cache: impl TestCache, ) where @@ -2849,10 +3002,12 @@ pub fn scan_cached_blocks_finds_received_notes( // Create a fake CompactBlock sending value to the address let value = NonNegativeAmount::const_from_u64(5); - let (h1, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); + let (h1, _, _) = st + .generate_next_block(&dfvk, AddressType::DefaultExternal, value) + .await; // Scan the cache - let summary = st.scan_cached_blocks(h1, 1); + let summary = st.scan_cached_blocks(h1, 1).await; assert_eq!(summary.scanned_range().start, h1); assert_eq!(summary.scanned_range().end, h1 + 1); assert_eq!(T::received_note_count(&summary), 1); @@ -2862,10 +3017,12 @@ pub fn scan_cached_blocks_finds_received_notes( // Create a second fake CompactBlock sending more value to the address let value2 = NonNegativeAmount::const_from_u64(7); - let (h2, _, _) = st.generate_next_block(&dfvk, AddressType::DefaultExternal, value2); + let (h2, _, _) = st + .generate_next_block(&dfvk, AddressType::DefaultExternal, value2) + .await; // Scan the cache again - let summary = st.scan_cached_blocks(h2, 1); + let summary = st.scan_cached_blocks(h2, 1).await; assert_eq!(summary.scanned_range().start, h2); assert_eq!(summary.scanned_range().end, h2 + 1); assert_eq!(T::received_note_count(&summary), 1); @@ -2878,7 +3035,7 @@ pub fn scan_cached_blocks_finds_received_notes( } // TODO: This test can probably be entirely removed, as the following test duplicates it entirely. -pub fn scan_cached_blocks_finds_change_notes( +pub async fn scan_cached_blocks_finds_change_notes( ds_factory: DSF, cache: impl TestCache, ) where @@ -2899,11 +3056,12 @@ pub fn scan_cached_blocks_finds_change_notes( // Create a fake CompactBlock sending value to the address let value = NonNegativeAmount::const_from_u64(5); - let (received_height, _, nf) = - st.generate_next_block(&dfvk, AddressType::DefaultExternal, value); + let (received_height, _, nf) = st + .generate_next_block(&dfvk, AddressType::DefaultExternal, value) + .await; // Scan the cache - st.scan_cached_blocks(received_height, 1); + st.scan_cached_blocks(received_height, 1).await; // Account balance should reflect the received note assert_eq!(st.get_total_balance(account.id()), value); @@ -2912,10 +3070,12 @@ pub fn scan_cached_blocks_finds_change_notes( let not_our_key = T::sk_to_fvk(&T::sk(&[0xf5; 32])); let to2 = T::fvk_default_address(¬_our_key); let value2 = NonNegativeAmount::const_from_u64(2); - let (spent_height, _) = st.generate_next_block_spending(&dfvk, (nf, value), to2, value2); + let (spent_height, _) = st + .generate_next_block_spending(&dfvk, (nf, value), to2, value2) + .await; // Scan the cache again - st.scan_cached_blocks(spent_height, 1); + st.scan_cached_blocks(spent_height, 1).await; // Account balance should equal the change assert_eq!( @@ -2924,7 +3084,7 @@ pub fn scan_cached_blocks_finds_change_notes( ); } -pub fn scan_cached_blocks_detects_spends_out_of_order( +pub async fn scan_cached_blocks_detects_spends_out_of_order( ds_factory: DSF, cache: impl TestCache, ) where @@ -2945,17 +3105,20 @@ pub fn scan_cached_blocks_detects_spends_out_of_order(dsf: DSF, cache: impl TestCache) +pub async fn transparent_balance_across_shielding(dsf: DSF, cache: impl TestCache) where DSF: DataStoreFactory, { @@ -129,10 +129,12 @@ where // Initialize the wallet with chain data that has no shielded notes for us. let not_our_key = ExtendedSpendingKey::master(&[]).to_diversifiable_full_viewing_key(); let not_our_value = NonNegativeAmount::const_from_u64(10000); - let (start_height, _, _) = - st.generate_next_block(¬_our_key, AddressType::DefaultExternal, not_our_value); + let (start_height, _, _) = st + .generate_next_block(¬_our_key, AddressType::DefaultExternal, not_our_value) + .await; for _ in 1..10 { - st.generate_next_block(¬_our_key, AddressType::DefaultExternal, not_our_value); + st.generate_next_block(¬_our_key, AddressType::DefaultExternal, not_our_value) + .await; } st.scan_cached_blocks(start_height, 10); @@ -219,7 +221,7 @@ where check_balance(&st, 0, NonNegativeAmount::ZERO); // Mine the shielding transaction. - let (mined_height, _) = st.generate_next_block_including(txid); + let (mined_height, _) = st.generate_next_block_including(txid).await; st.scan_cached_blocks(mined_height, 1); // The wallet should still have zero transparent balance. diff --git a/zcash_client_sqlite/src/chain.rs b/zcash_client_sqlite/src/chain.rs index 4ae89bf11..b72dfe306 100644 --- a/zcash_client_sqlite/src/chain.rs +++ b/zcash_client_sqlite/src/chain.rs @@ -328,92 +328,92 @@ mod tests { #[cfg(feature = "orchard")] use zcash_client_backend::data_api::testing::orchard::OrchardPoolTester; - #[test] - fn valid_chain_states_sapling() { - testing::pool::valid_chain_states::() + #[tokio::test] + async fn valid_chain_states_sapling() { + testing::pool::valid_chain_states::().await } - #[test] + #[tokio::test] #[cfg(feature = "orchard")] - fn valid_chain_states_orchard() { - testing::pool::valid_chain_states::() + async fn valid_chain_states_orchard() { + testing::pool::valid_chain_states::().await } - #[test] + #[tokio::test] #[cfg(feature = "orchard")] - fn invalid_chain_cache_disconnected_sapling() { - testing::pool::invalid_chain_cache_disconnected::() + async fn invalid_chain_cache_disconnected_sapling() { + testing::pool::invalid_chain_cache_disconnected::().await } - #[test] + #[tokio::test] #[cfg(feature = "orchard")] - fn invalid_chain_cache_disconnected_orchard() { - testing::pool::invalid_chain_cache_disconnected::() + async fn invalid_chain_cache_disconnected_orchard() { + testing::pool::invalid_chain_cache_disconnected::().await } - #[test] - fn data_db_truncation_sapling() { - testing::pool::data_db_truncation::() + #[tokio::test] + async fn data_db_truncation_sapling() { + testing::pool::data_db_truncation::().await } - #[test] + #[tokio::test] #[cfg(feature = "orchard")] - fn data_db_truncation_orchard() { - testing::pool::data_db_truncation::() + async fn data_db_truncation_orchard() { + testing::pool::data_db_truncation::().await } - #[test] - fn reorg_to_checkpoint_sapling() { - testing::pool::reorg_to_checkpoint::() + #[tokio::test] + async fn reorg_to_checkpoint_sapling() { + testing::pool::reorg_to_checkpoint::().await } - #[test] + #[tokio::test] #[cfg(feature = "orchard")] - fn reorg_to_checkpoint_orchard() { - testing::pool::reorg_to_checkpoint::() + async fn reorg_to_checkpoint_orchard() { + testing::pool::reorg_to_checkpoint::().await } - #[test] - fn scan_cached_blocks_allows_blocks_out_of_order_sapling() { - testing::pool::scan_cached_blocks_allows_blocks_out_of_order::() + #[tokio::test] + async fn scan_cached_blocks_allows_blocks_out_of_order_sapling() { + testing::pool::scan_cached_blocks_allows_blocks_out_of_order::().await } - #[test] + #[tokio::test] #[cfg(feature = "orchard")] - fn scan_cached_blocks_allows_blocks_out_of_order_orchard() { - testing::pool::scan_cached_blocks_allows_blocks_out_of_order::() + async fn scan_cached_blocks_allows_blocks_out_of_order_orchard() { + testing::pool::scan_cached_blocks_allows_blocks_out_of_order::().await } - #[test] - fn scan_cached_blocks_finds_received_notes_sapling() { - testing::pool::scan_cached_blocks_finds_received_notes::() + #[tokio::test] + async fn scan_cached_blocks_finds_received_notes_sapling() { + testing::pool::scan_cached_blocks_finds_received_notes::().await } - #[test] + #[tokio::test] #[cfg(feature = "orchard")] - fn scan_cached_blocks_finds_received_notes_orchard() { - testing::pool::scan_cached_blocks_finds_received_notes::() + async fn scan_cached_blocks_finds_received_notes_orchard() { + testing::pool::scan_cached_blocks_finds_received_notes::().await } - #[test] - fn scan_cached_blocks_finds_change_notes_sapling() { - testing::pool::scan_cached_blocks_finds_change_notes::() + #[tokio::test] + async fn scan_cached_blocks_finds_change_notes_sapling() { + testing::pool::scan_cached_blocks_finds_change_notes::().await } - #[test] + #[tokio::test] #[cfg(feature = "orchard")] - fn scan_cached_blocks_finds_change_notes_orchard() { - testing::pool::scan_cached_blocks_finds_change_notes::() + async fn scan_cached_blocks_finds_change_notes_orchard() { + testing::pool::scan_cached_blocks_finds_change_notes::().await } - #[test] - fn scan_cached_blocks_detects_spends_out_of_order_sapling() { - testing::pool::scan_cached_blocks_detects_spends_out_of_order::() + #[tokio::test] + async fn scan_cached_blocks_detects_spends_out_of_order_sapling() { + testing::pool::scan_cached_blocks_detects_spends_out_of_order::().await } - #[test] + #[tokio::test] #[cfg(feature = "orchard")] - fn scan_cached_blocks_detects_spends_out_of_order_orchard() { - testing::pool::scan_cached_blocks_detects_spends_out_of_order::() + async fn scan_cached_blocks_detects_spends_out_of_order_orchard() { + testing::pool::scan_cached_blocks_detects_spends_out_of_order::().await } } diff --git a/zcash_client_sqlite/src/lib.rs b/zcash_client_sqlite/src/lib.rs index 667b426f0..d7c6d842d 100644 --- a/zcash_client_sqlite/src/lib.rs +++ b/zcash_client_sqlite/src/lib.rs @@ -2382,14 +2382,14 @@ mod tests { } #[cfg(feature = "transparent-inputs")] - #[test] - fn transparent_receivers() { + #[tokio::test] + async fn transparent_receivers() { // Add an account to the wallet. use crate::testing::BlockCache; let st = TestBuilder::new() .with_data_store_factory(TestDbFactory::default()) - .with_block_cache(BlockCache::new()) + .with_block_cache(BlockCache::new().await) .with_account_from_sapling_activation(BlockHash([0; 32])) .build(); let account = st.test_account().unwrap(); @@ -2412,8 +2412,8 @@ mod tests { } #[cfg(feature = "unstable")] - #[test] - pub(crate) fn fsblockdb_api() { + #[tokio::test] + pub(crate) async fn fsblockdb_api() { use zcash_client_backend::data_api::testing::AddressType; use zcash_primitives::zip32; use zcash_protocol::consensus::NetworkConstants; @@ -2422,45 +2422,52 @@ mod tests { let mut st = TestBuilder::new() .with_data_store_factory(TestDbFactory::default()) - .with_block_cache(FsBlockCache::new()) + .with_block_cache(FsBlockCache::new().await) .build(); // The BlockMeta DB starts off empty. - assert_eq!(st.cache().get_max_cached_height().unwrap(), None); + assert_eq!(st.cache().get_max_cached_height().await.unwrap(), None); // Generate some fake CompactBlocks. let seed = [0u8; 32]; let hd_account_index = zip32::AccountId::ZERO; let extsk = sapling::spending_key(&seed, st.network().coin_type(), hd_account_index); let dfvk = extsk.to_diversifiable_full_viewing_key(); - let (h1, meta1, _) = st.generate_next_block( - &dfvk, - AddressType::DefaultExternal, - NonNegativeAmount::const_from_u64(5), - ); - let (h2, meta2, _) = st.generate_next_block( - &dfvk, - AddressType::DefaultExternal, - NonNegativeAmount::const_from_u64(10), - ); + let (h1, meta1, _) = st + .generate_next_block( + &dfvk, + AddressType::DefaultExternal, + NonNegativeAmount::const_from_u64(5), + ) + .await; + let (h2, meta2, _) = st + .generate_next_block( + &dfvk, + AddressType::DefaultExternal, + NonNegativeAmount::const_from_u64(10), + ) + .await; // The BlockMeta DB is not updated until we do so explicitly. - assert_eq!(st.cache().get_max_cached_height().unwrap(), None); + assert_eq!(st.cache().get_max_cached_height().await.unwrap(), None); // Inform the BlockMeta DB about the newly-persisted CompactBlocks. - st.cache().write_block_metadata(&[meta1, meta2]).unwrap(); + st.cache() + .write_block_metadata(&[meta1, meta2]) + .await + .unwrap(); // The BlockMeta DB now sees blocks up to height 2. - assert_eq!(st.cache().get_max_cached_height().unwrap(), Some(h2),); - assert_eq!(st.cache().find_block(h1).unwrap(), Some(meta1)); - assert_eq!(st.cache().find_block(h2).unwrap(), Some(meta2)); - assert_eq!(st.cache().find_block(h2 + 1).unwrap(), None); + assert_eq!(st.cache().get_max_cached_height().await.unwrap(), Some(h2),); + assert_eq!(st.cache().find_block(h1).await.unwrap(), Some(meta1)); + assert_eq!(st.cache().find_block(h2).await.unwrap(), Some(meta2)); + assert_eq!(st.cache().find_block(h2 + 1).await.unwrap(), None); // Rewinding to height 1 should cause the metadata for height 2 to be deleted. - st.cache().truncate_to_height(h1).unwrap(); - assert_eq!(st.cache().get_max_cached_height().unwrap(), Some(h1)); - assert_eq!(st.cache().find_block(h1).unwrap(), Some(meta1)); - assert_eq!(st.cache().find_block(h2).unwrap(), None); - assert_eq!(st.cache().find_block(h2 + 1).unwrap(), None); + st.cache().truncate_to_height(h1).await.unwrap(); + assert_eq!(st.cache().get_max_cached_height().await.unwrap(), Some(h1)); + assert_eq!(st.cache().find_block(h1).await.unwrap(), Some(meta1)); + assert_eq!(st.cache().find_block(h2).await.unwrap(), None); + assert_eq!(st.cache().find_block(h2 + 1).await.unwrap(), None); } } diff --git a/zcash_client_sqlite/src/testing.rs b/zcash_client_sqlite/src/testing.rs index 215412fc1..0ebf4d480 100644 --- a/zcash_client_sqlite/src/testing.rs +++ b/zcash_client_sqlite/src/testing.rs @@ -30,10 +30,10 @@ pub(crate) struct BlockCache { } impl BlockCache { - pub(crate) fn new() -> Self { + pub(crate) async fn new() -> Self { let cache_file = NamedTempFile::new().unwrap(); let db_cache = BlockDb::for_path(cache_file.path()).unwrap(); - init_cache_database(&db_cache).unwrap(); + init_cache_database(&db_cache).await.unwrap(); BlockCache { _cache_file: cache_file, @@ -93,10 +93,10 @@ pub(crate) struct FsBlockCache { #[cfg(feature = "unstable")] impl FsBlockCache { - pub(crate) fn new() -> Self { + pub(crate) async fn new() -> Self { let fsblockdb_root = tempfile::tempdir().unwrap(); let mut db_meta = FsBlockDb::for_path(&fsblockdb_root).unwrap(); - init_blockmeta_db(&mut db_meta).unwrap(); + init_blockmeta_db(&mut db_meta).await.unwrap(); FsBlockCache { fsblockdb_root, diff --git a/zcash_client_sqlite/src/testing/pool.rs b/zcash_client_sqlite/src/testing/pool.rs index 8465a582a..5aeb13887 100644 --- a/zcash_client_sqlite/src/testing/pool.rs +++ b/zcash_client_sqlite/src/testing/pool.rs @@ -29,25 +29,27 @@ impl ShieldedPoolPersistence for OrchardPoolTester { const TABLES_PREFIX: &'static str = ORCHARD_TABLES_PREFIX; } -pub(crate) fn send_single_step_proposed_transfer() { +pub(crate) async fn send_single_step_proposed_transfer() { zcash_client_backend::data_api::testing::pool::send_single_step_proposed_transfer::( TestDbFactory::default(), - BlockCache::new(), + BlockCache::new().await, ) + .await } -pub(crate) fn send_with_multiple_change_outputs() { +pub(crate) async fn send_with_multiple_change_outputs() { zcash_client_backend::data_api::testing::pool::send_with_multiple_change_outputs::( TestDbFactory::default(), - BlockCache::new(), + BlockCache::new().await, ) + .await } #[cfg(feature = "transparent-inputs")] -pub(crate) fn send_multi_step_proposed_transfer() { +pub(crate) async fn send_multi_step_proposed_transfer() { zcash_client_backend::data_api::testing::pool::send_multi_step_proposed_transfer::( TestDbFactory::default(), - BlockCache::new(), + BlockCache::new().await, |e, account_id, expected_bad_index| { matches!( e, @@ -55,14 +57,15 @@ pub(crate) fn send_multi_step_proposed_transfer() { if acct == &account_id && bad_index == &expected_bad_index) }, ) + .await } #[cfg(feature = "transparent-inputs")] -pub(crate) fn proposal_fails_if_not_all_ephemeral_outputs_consumed() { +pub(crate) async fn proposal_fails_if_not_all_ephemeral_outputs_consumed() { zcash_client_backend::data_api::testing::pool::proposal_fails_if_not_all_ephemeral_outputs_consumed::( TestDbFactory::default(), - BlockCache::new(), - ) + BlockCache::new().await, + ).await } pub(crate) fn create_to_address_fails_on_incorrect_usk() { @@ -77,180 +80,201 @@ pub(crate) fn proposal_fails_with_no_blocks() { ) } -pub(crate) fn spend_fails_on_unverified_notes() { +pub(crate) async fn spend_fails_on_unverified_notes() { zcash_client_backend::data_api::testing::pool::spend_fails_on_unverified_notes::( TestDbFactory::default(), - BlockCache::new(), + BlockCache::new().await, ) + .await } -pub(crate) fn spend_fails_on_locked_notes() { +pub(crate) async fn spend_fails_on_locked_notes() { zcash_client_backend::data_api::testing::pool::spend_fails_on_locked_notes::( TestDbFactory::default(), - BlockCache::new(), + BlockCache::new().await, ) + .await } -pub(crate) fn ovk_policy_prevents_recovery_from_chain() { +pub(crate) async fn ovk_policy_prevents_recovery_from_chain() { zcash_client_backend::data_api::testing::pool::ovk_policy_prevents_recovery_from_chain::( TestDbFactory::default(), - BlockCache::new(), + BlockCache::new().await, ) + .await } -pub(crate) fn spend_succeeds_to_t_addr_zero_change() { +pub(crate) async fn spend_succeeds_to_t_addr_zero_change() { zcash_client_backend::data_api::testing::pool::spend_succeeds_to_t_addr_zero_change::( TestDbFactory::default(), - BlockCache::new(), + BlockCache::new().await, ) + .await } -pub(crate) fn change_note_spends_succeed() { +pub(crate) async fn change_note_spends_succeed() { zcash_client_backend::data_api::testing::pool::change_note_spends_succeed::( TestDbFactory::default(), - BlockCache::new(), + BlockCache::new().await, ) + .await } -pub(crate) fn external_address_change_spends_detected_in_restore_from_seed< +pub(crate) async fn external_address_change_spends_detected_in_restore_from_seed< T: ShieldedPoolTester, >() { zcash_client_backend::data_api::testing::pool::external_address_change_spends_detected_in_restore_from_seed::( TestDbFactory::default(), - BlockCache::new(), - ) + BlockCache::new().await, + ).await } #[allow(dead_code)] -pub(crate) fn zip317_spend() { +pub(crate) async fn zip317_spend() { zcash_client_backend::data_api::testing::pool::zip317_spend::( TestDbFactory::default(), - BlockCache::new(), + BlockCache::new().await, ) + .await } #[cfg(feature = "transparent-inputs")] -pub(crate) fn shield_transparent() { +pub(crate) async fn shield_transparent() { zcash_client_backend::data_api::testing::pool::shield_transparent::( TestDbFactory::default(), - BlockCache::new(), + BlockCache::new().await, ) + .await } // FIXME: This requires fixes to the test framework. #[allow(dead_code)] -pub(crate) fn birthday_in_anchor_shard() { +pub(crate) async fn birthday_in_anchor_shard() { zcash_client_backend::data_api::testing::pool::birthday_in_anchor_shard::( TestDbFactory::default(), - BlockCache::new(), + BlockCache::new().await, ) + .await } -pub(crate) fn checkpoint_gaps() { +pub(crate) async fn checkpoint_gaps() { zcash_client_backend::data_api::testing::pool::checkpoint_gaps::( TestDbFactory::default(), - BlockCache::new(), + BlockCache::new().await, ) + .await } #[cfg(feature = "orchard")] -pub(crate) fn pool_crossing_required() { +pub(crate) async fn pool_crossing_required() { zcash_client_backend::data_api::testing::pool::pool_crossing_required::( TestDbFactory::default(), - BlockCache::new(), + BlockCache::new().await, ) + .await } #[cfg(feature = "orchard")] -pub(crate) fn fully_funded_fully_private() { +pub(crate) async fn fully_funded_fully_private() { zcash_client_backend::data_api::testing::pool::fully_funded_fully_private::( TestDbFactory::default(), - BlockCache::new(), + BlockCache::new().await, ) + .await } #[cfg(all(feature = "orchard", feature = "transparent-inputs"))] -pub(crate) fn fully_funded_send_to_t() { +pub(crate) async fn fully_funded_send_to_t() { zcash_client_backend::data_api::testing::pool::fully_funded_send_to_t::( TestDbFactory::default(), - BlockCache::new(), + BlockCache::new().await, ) + .await } #[cfg(feature = "orchard")] -pub(crate) fn multi_pool_checkpoint() { +pub(crate) async fn multi_pool_checkpoint() { zcash_client_backend::data_api::testing::pool::multi_pool_checkpoint::( TestDbFactory::default(), - BlockCache::new(), + BlockCache::new().await, ) + .await } #[cfg(feature = "orchard")] -pub(crate) fn multi_pool_checkpoints_with_pruning< +pub(crate) async fn multi_pool_checkpoints_with_pruning< P0: ShieldedPoolTester, P1: ShieldedPoolTester, >() { zcash_client_backend::data_api::testing::pool::multi_pool_checkpoints_with_pruning::( TestDbFactory::default(), - BlockCache::new(), + BlockCache::new().await, ) + .await } -pub(crate) fn valid_chain_states() { +pub(crate) async fn valid_chain_states() { zcash_client_backend::data_api::testing::pool::valid_chain_states::( TestDbFactory::default(), - BlockCache::new(), + BlockCache::new().await, ) + .await } // FIXME: This requires fixes to the test framework. #[allow(dead_code)] -pub(crate) fn invalid_chain_cache_disconnected() { +pub(crate) async fn invalid_chain_cache_disconnected() { zcash_client_backend::data_api::testing::pool::invalid_chain_cache_disconnected::( TestDbFactory::default(), - BlockCache::new(), + BlockCache::new().await, ) + .await } -pub(crate) fn data_db_truncation() { +pub(crate) async fn data_db_truncation() { zcash_client_backend::data_api::testing::pool::data_db_truncation::( TestDbFactory::default(), - BlockCache::new(), + BlockCache::new().await, ) + .await } -pub(crate) fn reorg_to_checkpoint() { +pub(crate) async fn reorg_to_checkpoint() { zcash_client_backend::data_api::testing::pool::reorg_to_checkpoint::( TestDbFactory::default(), - BlockCache::new(), + BlockCache::new().await, ) + .await } -pub(crate) fn scan_cached_blocks_allows_blocks_out_of_order() { +pub(crate) async fn scan_cached_blocks_allows_blocks_out_of_order() { zcash_client_backend::data_api::testing::pool::scan_cached_blocks_allows_blocks_out_of_order::( TestDbFactory::default(), - BlockCache::new(), - ) + BlockCache::new().await, + ).await } -pub(crate) fn scan_cached_blocks_finds_received_notes() { +pub(crate) async fn scan_cached_blocks_finds_received_notes() { zcash_client_backend::data_api::testing::pool::scan_cached_blocks_finds_received_notes::( TestDbFactory::default(), - BlockCache::new(), + BlockCache::new().await, ) + .await } // TODO: This test can probably be entirely removed, as the following test duplicates it entirely. -pub(crate) fn scan_cached_blocks_finds_change_notes() { +pub(crate) async fn scan_cached_blocks_finds_change_notes() { zcash_client_backend::data_api::testing::pool::scan_cached_blocks_finds_change_notes::( TestDbFactory::default(), - BlockCache::new(), + BlockCache::new().await, ) + .await } -pub(crate) fn scan_cached_blocks_detects_spends_out_of_order() { +pub(crate) async fn scan_cached_blocks_detects_spends_out_of_order() { zcash_client_backend::data_api::testing::pool::scan_cached_blocks_detects_spends_out_of_order::< T, _, - >(TestDbFactory::default(), BlockCache::new()) + >(TestDbFactory::default(), BlockCache::new().await) + .await } diff --git a/zcash_client_sqlite/src/wallet.rs b/zcash_client_sqlite/src/wallet.rs index 43d8d7777..b0f98820c 100644 --- a/zcash_client_sqlite/src/wallet.rs +++ b/zcash_client_sqlite/src/wallet.rs @@ -3677,15 +3677,15 @@ mod tests { } } - #[test] - fn block_fully_scanned() { - check_block_fully_scanned(TestDbFactory::default()) + #[tokio::test] + async fn block_fully_scanned() { + check_block_fully_scanned(TestDbFactory::default()).await } - fn check_block_fully_scanned(dsf: DsF) { + async fn check_block_fully_scanned(dsf: DsF) { let mut st = TestBuilder::new() .with_data_store_factory(dsf) - .with_block_cache(BlockCache::new()) + .with_block_cache(BlockCache::new().await) .with_account_from_sapling_activation(BlockHash([0; 32])) .build(); @@ -3703,49 +3703,53 @@ mod tests { let not_our_key = ExtendedSpendingKey::master(&[]).to_diversifiable_full_viewing_key(); let not_our_value = NonNegativeAmount::const_from_u64(10000); let start_height = st.sapling_activation_height(); - let _ = st.generate_block_at( - start_height, - BlockHash([0; 32]), - &[FakeCompactOutput::new( - ¬_our_key, - AddressType::DefaultExternal, - not_our_value, - )], - 0, - 0, - false, - ); - let (mid_height, _, _) = - st.generate_next_block(¬_our_key, AddressType::DefaultExternal, not_our_value); - let (end_height, _, _) = - st.generate_next_block(¬_our_key, AddressType::DefaultExternal, not_our_value); + let _ = st + .generate_block_at( + start_height, + BlockHash([0; 32]), + &[FakeCompactOutput::new( + ¬_our_key, + AddressType::DefaultExternal, + not_our_value, + )], + 0, + 0, + false, + ) + .await; + let (mid_height, _, _) = st + .generate_next_block(¬_our_key, AddressType::DefaultExternal, not_our_value) + .await; + let (end_height, _, _) = st + .generate_next_block(¬_our_key, AddressType::DefaultExternal, not_our_value) + .await; // Scan the last block first - st.scan_cached_blocks(end_height, 1); + st.scan_cached_blocks(end_height, 1).await; // The wallet should still have no fully-scanned block, as no scanned block range // overlaps the wallet's birthday. assert_eq!(block_fully_scanned(&st), None); // Scan the block at the wallet's birthday height. - st.scan_cached_blocks(start_height, 1); + st.scan_cached_blocks(start_height, 1).await; // The fully-scanned height should now be that of the scanned block. assert_eq!(block_fully_scanned(&st), Some(start_height)); // Scan the block in between the two previous blocks. - st.scan_cached_blocks(mid_height, 1); + st.scan_cached_blocks(mid_height, 1).await; // The fully-scanned height should now be the latest block, as the two disjoint // ranges have been connected. assert_eq!(block_fully_scanned(&st), Some(end_height)); } - #[test] - fn test_account_birthday() { + #[tokio::test] + async fn test_account_birthday() { let st = TestBuilder::new() .with_data_store_factory(TestDbFactory::default()) - .with_block_cache(BlockCache::new()) + .with_block_cache(BlockCache::new().await) .with_account_from_sapling_activation(BlockHash([0; 32])) .build(); diff --git a/zcash_client_sqlite/src/wallet/init/migrations/fix_bad_change_flagging.rs b/zcash_client_sqlite/src/wallet/init/migrations/fix_bad_change_flagging.rs index efab795a6..e5aaeabca 100644 --- a/zcash_client_sqlite/src/wallet/init/migrations/fix_bad_change_flagging.rs +++ b/zcash_client_sqlite/src/wallet/init/migrations/fix_bad_change_flagging.rs @@ -102,9 +102,9 @@ mod tests { } #[cfg(feature = "transparent-inputs")] - fn shield_transparent() { + async fn shield_transparent() { let ds_factory = TestDbFactory::new(super::DEPENDENCIES.to_vec()); - let cache = BlockCache::new(); + let cache = BlockCache::new().await; let mut st = TestBuilder::new() .with_data_store_factory(ds_factory) .with_block_cache(cache) @@ -122,12 +122,14 @@ mod tests { let taddr = uaddr.transparent().unwrap(); // Ensure that the wallet has at least one block - let (h, _, _) = st.generate_next_block( - &dfvk, - AddressType::Internal, - Zatoshis::const_from_u64(50000), - ); - st.scan_cached_blocks(h, 1); + let (h, _, _) = st + .generate_next_block( + &dfvk, + AddressType::Internal, + Zatoshis::const_from_u64(50000), + ) + .await; + st.scan_cached_blocks(h, 1).await; let utxo = WalletTransparentOutput::from_parts( OutPoint::fake(), @@ -175,8 +177,8 @@ mod tests { // Prior to the fix that removes the source of the error this migration is addressing, // this scanning will result in a state where `tx.is_shielding() == false`. However, // we can't validate that here, because after that fix, this test would fail. - let (h, _) = st.generate_next_block_including(*txids.first()); - st.scan_cached_blocks(h, 1); + let (h, _) = st.generate_next_block_including(*txids.first()).await; + st.scan_cached_blocks(h, 1).await; // Complete the migration to resolve the incorrect change flag value. init_wallet_db(st.wallet_mut().db_mut(), None).unwrap(); @@ -189,17 +191,17 @@ mod tests { assert!(tx.is_shielding()); } - #[test] + #[tokio::test] #[cfg(feature = "transparent-inputs")] - fn sapling_shield_transparent() { - shield_transparent::(); + async fn sapling_shield_transparent() { + shield_transparent::().await; } - #[test] + #[tokio::test] #[cfg(all(feature = "orchard", feature = "transparent-inputs"))] - fn orchard_shield_transparent() { + async fn orchard_shield_transparent() { use zcash_client_backend::data_api::testing::orchard::OrchardPoolTester; - shield_transparent::(); + shield_transparent::().await; } } diff --git a/zcash_client_sqlite/src/wallet/orchard.rs b/zcash_client_sqlite/src/wallet/orchard.rs index 046b81f6b..61688c16e 100644 --- a/zcash_client_sqlite/src/wallet/orchard.rs +++ b/zcash_client_sqlite/src/wallet/orchard.rs @@ -394,26 +394,27 @@ pub(crate) mod tests { use crate::testing::{self}; - #[test] - fn send_single_step_proposed_transfer() { - testing::pool::send_single_step_proposed_transfer::() + #[tokio::test] + async fn send_single_step_proposed_transfer() { + testing::pool::send_single_step_proposed_transfer::().await } - #[test] - fn send_with_multiple_change_outputs() { - testing::pool::send_with_multiple_change_outputs::() + #[tokio::test] + async fn send_with_multiple_change_outputs() { + testing::pool::send_with_multiple_change_outputs::().await } - #[test] + #[tokio::test] #[cfg(feature = "transparent-inputs")] - fn send_multi_step_proposed_transfer() { - testing::pool::send_multi_step_proposed_transfer::() + async fn send_multi_step_proposed_transfer() { + testing::pool::send_multi_step_proposed_transfer::().await } - #[test] + #[tokio::test] #[cfg(feature = "transparent-inputs")] - fn proposal_fails_if_not_all_ephemeral_outputs_consumed() { + async fn proposal_fails_if_not_all_ephemeral_outputs_consumed() { testing::pool::proposal_fails_if_not_all_ephemeral_outputs_consumed::() + .await } #[test] @@ -426,89 +427,91 @@ pub(crate) mod tests { testing::pool::proposal_fails_with_no_blocks::() } - #[test] - fn spend_fails_on_unverified_notes() { - testing::pool::spend_fails_on_unverified_notes::() + #[tokio::test] + async fn spend_fails_on_unverified_notes() { + testing::pool::spend_fails_on_unverified_notes::().await } - #[test] - fn spend_fails_on_locked_notes() { - testing::pool::spend_fails_on_locked_notes::() + #[tokio::test] + async fn spend_fails_on_locked_notes() { + testing::pool::spend_fails_on_locked_notes::().await } - #[test] - fn ovk_policy_prevents_recovery_from_chain() { - testing::pool::ovk_policy_prevents_recovery_from_chain::() + #[tokio::test] + async fn ovk_policy_prevents_recovery_from_chain() { + testing::pool::ovk_policy_prevents_recovery_from_chain::().await } - #[test] - fn spend_succeeds_to_t_addr_zero_change() { - testing::pool::spend_succeeds_to_t_addr_zero_change::() + #[tokio::test] + async fn spend_succeeds_to_t_addr_zero_change() { + testing::pool::spend_succeeds_to_t_addr_zero_change::().await } - #[test] - fn change_note_spends_succeed() { - testing::pool::change_note_spends_succeed::() + #[tokio::test] + async fn change_note_spends_succeed() { + testing::pool::change_note_spends_succeed::().await } - #[test] - fn external_address_change_spends_detected_in_restore_from_seed() { + #[tokio::test] + async fn external_address_change_spends_detected_in_restore_from_seed() { testing::pool::external_address_change_spends_detected_in_restore_from_seed::< OrchardPoolTester, >() + .await } - #[test] + #[tokio::test] #[ignore] // FIXME: #1316 This requires support for dust outputs. #[cfg(not(feature = "expensive-tests"))] - fn zip317_spend() { - testing::pool::zip317_spend::() + async fn zip317_spend() { + testing::pool::zip317_spend::().await } - #[test] + #[tokio::test] #[cfg(feature = "transparent-inputs")] - fn shield_transparent() { - testing::pool::shield_transparent::() + async fn shield_transparent() { + testing::pool::shield_transparent::().await } - #[test] - fn birthday_in_anchor_shard() { - testing::pool::birthday_in_anchor_shard::() + #[tokio::test] + async fn birthday_in_anchor_shard() { + testing::pool::birthday_in_anchor_shard::().await } - #[test] - fn checkpoint_gaps() { - testing::pool::checkpoint_gaps::() + #[tokio::test] + async fn checkpoint_gaps() { + testing::pool::checkpoint_gaps::().await } - #[test] - fn scan_cached_blocks_detects_spends_out_of_order() { - testing::pool::scan_cached_blocks_detects_spends_out_of_order::() + #[tokio::test] + async fn scan_cached_blocks_detects_spends_out_of_order() { + testing::pool::scan_cached_blocks_detects_spends_out_of_order::().await } - #[test] - fn pool_crossing_required() { - testing::pool::pool_crossing_required::() + #[tokio::test] + async fn pool_crossing_required() { + testing::pool::pool_crossing_required::().await } - #[test] - fn fully_funded_fully_private() { - testing::pool::fully_funded_fully_private::() + #[tokio::test] + async fn fully_funded_fully_private() { + testing::pool::fully_funded_fully_private::().await } - #[test] + #[tokio::test] #[cfg(feature = "transparent-inputs")] - fn fully_funded_send_to_t() { - testing::pool::fully_funded_send_to_t::() + async fn fully_funded_send_to_t() { + testing::pool::fully_funded_send_to_t::().await } - #[test] - fn multi_pool_checkpoint() { - testing::pool::multi_pool_checkpoint::() + #[tokio::test] + async fn multi_pool_checkpoint() { + testing::pool::multi_pool_checkpoint::().await } - #[test] - fn multi_pool_checkpoints_with_pruning() { + #[tokio::test] + async fn multi_pool_checkpoints_with_pruning() { testing::pool::multi_pool_checkpoints_with_pruning::() + .await } } diff --git a/zcash_client_sqlite/src/wallet/sapling.rs b/zcash_client_sqlite/src/wallet/sapling.rs index c9cf157a4..2b2be3c1b 100644 --- a/zcash_client_sqlite/src/wallet/sapling.rs +++ b/zcash_client_sqlite/src/wallet/sapling.rs @@ -407,26 +407,27 @@ pub(crate) mod tests { #[cfg(feature = "orchard")] use zcash_client_backend::data_api::testing::orchard::OrchardPoolTester; - #[test] - fn send_single_step_proposed_transfer() { - testing::pool::send_single_step_proposed_transfer::() + #[tokio::test] + async fn send_single_step_proposed_transfer() { + testing::pool::send_single_step_proposed_transfer::().await } - #[test] - fn send_with_multiple_change_outputs() { - testing::pool::send_with_multiple_change_outputs::() + #[tokio::test] + async fn send_with_multiple_change_outputs() { + testing::pool::send_with_multiple_change_outputs::().await } - #[test] + #[tokio::test] #[cfg(feature = "transparent-inputs")] - fn send_multi_step_proposed_transfer() { - testing::pool::send_multi_step_proposed_transfer::() + async fn send_multi_step_proposed_transfer() { + testing::pool::send_multi_step_proposed_transfer::().await } - #[test] + #[tokio::test] #[cfg(feature = "transparent-inputs")] - fn proposal_fails_if_not_all_ephemeral_outputs_consumed() { + async fn proposal_fails_if_not_all_ephemeral_outputs_consumed() { testing::pool::proposal_fails_if_not_all_ephemeral_outputs_consumed::() + .await } #[test] @@ -439,93 +440,95 @@ pub(crate) mod tests { testing::pool::proposal_fails_with_no_blocks::() } - #[test] - fn spend_fails_on_unverified_notes() { - testing::pool::spend_fails_on_unverified_notes::() + #[tokio::test] + async fn spend_fails_on_unverified_notes() { + testing::pool::spend_fails_on_unverified_notes::().await } - #[test] - fn spend_fails_on_locked_notes() { - testing::pool::spend_fails_on_locked_notes::() + #[tokio::test] + async fn spend_fails_on_locked_notes() { + testing::pool::spend_fails_on_locked_notes::().await } - #[test] - fn ovk_policy_prevents_recovery_from_chain() { - testing::pool::ovk_policy_prevents_recovery_from_chain::() + #[tokio::test] + async fn ovk_policy_prevents_recovery_from_chain() { + testing::pool::ovk_policy_prevents_recovery_from_chain::().await } - #[test] - fn spend_succeeds_to_t_addr_zero_change() { - testing::pool::spend_succeeds_to_t_addr_zero_change::() + #[tokio::test] + async fn spend_succeeds_to_t_addr_zero_change() { + testing::pool::spend_succeeds_to_t_addr_zero_change::().await } - #[test] - fn change_note_spends_succeed() { - testing::pool::change_note_spends_succeed::() + #[tokio::test] + async fn change_note_spends_succeed() { + testing::pool::change_note_spends_succeed::().await } - #[test] - fn external_address_change_spends_detected_in_restore_from_seed() { + #[tokio::test] + async fn external_address_change_spends_detected_in_restore_from_seed() { testing::pool::external_address_change_spends_detected_in_restore_from_seed::< SaplingPoolTester, >() + .await } - #[test] + #[tokio::test] #[ignore] // FIXME: #1316 This requires support for dust outputs. #[cfg(not(feature = "expensive-tests"))] - fn zip317_spend() { - testing::pool::zip317_spend::() + async fn zip317_spend() { + testing::pool::zip317_spend::().await } - #[test] + #[tokio::test] #[cfg(feature = "transparent-inputs")] - fn shield_transparent() { - testing::pool::shield_transparent::() + async fn shield_transparent() { + testing::pool::shield_transparent::().await } - #[test] - fn birthday_in_anchor_shard() { - testing::pool::birthday_in_anchor_shard::() + #[tokio::test] + async fn birthday_in_anchor_shard() { + testing::pool::birthday_in_anchor_shard::().await } - #[test] - fn checkpoint_gaps() { - testing::pool::checkpoint_gaps::() + #[tokio::test] + async fn checkpoint_gaps() { + testing::pool::checkpoint_gaps::().await } - #[test] - fn scan_cached_blocks_detects_spends_out_of_order() { - testing::pool::scan_cached_blocks_detects_spends_out_of_order::() + #[tokio::test] + async fn scan_cached_blocks_detects_spends_out_of_order() { + testing::pool::scan_cached_blocks_detects_spends_out_of_order::().await } - #[test] + #[tokio::test] #[cfg(feature = "orchard")] - fn pool_crossing_required() { - testing::pool::pool_crossing_required::() + async fn pool_crossing_required() { + testing::pool::pool_crossing_required::().await } - #[test] + #[tokio::test] #[cfg(feature = "orchard")] - fn fully_funded_fully_private() { - testing::pool::fully_funded_fully_private::() + async fn fully_funded_fully_private() { + testing::pool::fully_funded_fully_private::().await } - #[test] + #[tokio::test] #[cfg(all(feature = "orchard", feature = "transparent-inputs"))] - fn fully_funded_send_to_t() { - testing::pool::fully_funded_send_to_t::() + async fn fully_funded_send_to_t() { + testing::pool::fully_funded_send_to_t::().await } - #[test] + #[tokio::test] #[cfg(feature = "orchard")] - fn multi_pool_checkpoint() { - testing::pool::multi_pool_checkpoint::() + async fn multi_pool_checkpoint() { + testing::pool::multi_pool_checkpoint::().await } - #[test] + #[tokio::test] #[cfg(feature = "orchard")] - fn multi_pool_checkpoints_with_pruning() { + async fn multi_pool_checkpoints_with_pruning() { testing::pool::multi_pool_checkpoints_with_pruning::() + .await } } diff --git a/zcash_client_sqlite/src/wallet/scanning.rs b/zcash_client_sqlite/src/wallet/scanning.rs index c41ed0684..e54751bcf 100644 --- a/zcash_client_sqlite/src/wallet/scanning.rs +++ b/zcash_client_sqlite/src/wallet/scanning.rs @@ -605,18 +605,18 @@ pub(crate) mod tests { zcash_primitives::memo::Memo, }; - #[test] - fn sapling_scan_complete() { - scan_complete::(); + #[tokio::test] + async fn sapling_scan_complete() { + scan_complete::().await; } - #[test] + #[tokio::test] #[cfg(feature = "orchard")] - fn orchard_scan_complete() { - scan_complete::(); + async fn orchard_scan_complete() { + scan_complete::().await; } - fn scan_complete() { + async fn scan_complete() { use ScanPriority::*; // We'll start inserting leaf notes 5 notes after the end of the third subtree, with a gap @@ -630,7 +630,7 @@ pub(crate) mod tests { let mut st = TestBuilder::new() .with_data_store_factory(TestDbFactory::default()) - .with_block_cache(BlockCache::new()) + .with_block_cache(BlockCache::new().await) .with_initial_chain_state(|rng, network| { let sapling_activation_height = network.activation_height(NetworkUpgrade::Sapling).unwrap(); @@ -697,17 +697,19 @@ pub(crate) mod tests { initial_sapling_tree_size, initial_orchard_tree_size, false, - ); + ) + .await; for _ in 1..=10 { st.generate_next_block( &dfvk, AddressType::DefaultExternal, NonNegativeAmount::const_from_u64(10000), - ); + ) + .await; } - st.scan_cached_blocks(initial_height, 10); + st.scan_cached_blocks(initial_height, 10).await; // Verify the that adjacent range needed to make the note spendable has been prioritized. let sap_active = u32::from(sapling_activation_height); @@ -784,7 +786,7 @@ pub(crate) mod tests { /// * The wallet birthday is located `birthday_offset` blocks into the second shard. /// * The note commitment tree contains 2^16+1235 notes at the end of the block prior to the /// wallet birthday. - pub(crate) fn test_with_nu5_birthday_offset( + pub(crate) async fn test_with_nu5_birthday_offset( initial_shard_blocks: u32, birthday_offset: u32, prior_block_hash: BlockHash, @@ -797,7 +799,7 @@ pub(crate) mod tests { ) { let st = TestBuilder::new() .with_data_store_factory(TestDbFactory::default()) - .with_block_cache(BlockCache::new()) + .with_block_cache(BlockCache::new().await) .with_initial_chain_state(|rng, network| { // We set the Sapling and Orchard frontiers at the birthday height to be // 1234 notes into the second shard. @@ -859,23 +861,23 @@ pub(crate) mod tests { (st, dfvk, birthday, sap_active.into()) } - #[test] - fn sapling_create_account_creates_ignored_range() { - create_account_creates_ignored_range::(); + #[tokio::test] + async fn sapling_create_account_creates_ignored_range() { + create_account_creates_ignored_range::().await; } - #[test] + #[tokio::test] #[cfg(feature = "orchard")] - fn orchard_create_account_creates_ignored_range() { - create_account_creates_ignored_range::(); + async fn orchard_create_account_creates_ignored_range() { + create_account_creates_ignored_range::().await; } - fn create_account_creates_ignored_range() { + async fn create_account_creates_ignored_range() { use ScanPriority::*; // Use a non-zero birthday offset because Sapling and NU5 are activated at the same height. let (st, _, birthday, sap_active) = - test_with_nu5_birthday_offset::(50, 26, BlockHash([0; 32]), true); + test_with_nu5_birthday_offset::(50, 26, BlockHash([0; 32]), true).await; let birthday_height = birthday.height().into(); let expected = vec![ @@ -886,13 +888,13 @@ pub(crate) mod tests { assert_eq!(actual, expected); } - #[test] - fn update_chain_tip_before_create_account() { + #[tokio::test] + async fn update_chain_tip_before_create_account() { use ScanPriority::*; let mut st = TestBuilder::new() .with_data_store_factory(TestDbFactory::default()) - .with_block_cache(BlockCache::new()) + .with_block_cache(BlockCache::new().await) .build(); let sap_active = st.sapling_activation_height(); @@ -930,23 +932,23 @@ pub(crate) mod tests { assert_eq!(actual, expected); } - #[test] - fn sapling_update_chain_tip_with_no_subtree_roots() { - update_chain_tip_with_no_subtree_roots::(); + #[tokio::test] + async fn sapling_update_chain_tip_with_no_subtree_roots() { + update_chain_tip_with_no_subtree_roots::().await; } #[cfg(feature = "orchard")] - #[test] - fn orchard_update_chain_tip_with_no_subtree_roots() { - update_chain_tip_with_no_subtree_roots::(); + #[tokio::test] + async fn orchard_update_chain_tip_with_no_subtree_roots() { + update_chain_tip_with_no_subtree_roots::().await; } - fn update_chain_tip_with_no_subtree_roots() { + async fn update_chain_tip_with_no_subtree_roots() { use ScanPriority::*; // Use a non-zero birthday offset because Sapling and NU5 are activated at the same height. let (mut st, _, birthday, sap_active) = - test_with_nu5_birthday_offset::(50, 26, BlockHash([0; 32]), false); + test_with_nu5_birthday_offset::(50, 26, BlockHash([0; 32]), false).await; // Set up the following situation: // @@ -975,23 +977,23 @@ pub(crate) mod tests { assert_eq!(actual, expected); } - #[test] - fn sapling_update_chain_tip_when_never_scanned() { - update_chain_tip_when_never_scanned::(); + #[tokio::test] + async fn sapling_update_chain_tip_when_never_scanned() { + update_chain_tip_when_never_scanned::().await; } #[cfg(feature = "orchard")] - #[test] - fn orchard_update_chain_tip_when_never_scanned() { - update_chain_tip_when_never_scanned::(); + #[tokio::test] + async fn orchard_update_chain_tip_when_never_scanned() { + update_chain_tip_when_never_scanned::().await; } - fn update_chain_tip_when_never_scanned() { + async fn update_chain_tip_when_never_scanned() { use ScanPriority::*; // Use a non-zero birthday offset because Sapling and NU5 are activated at the same height. let (mut st, _, birthday, sap_active) = - test_with_nu5_birthday_offset::(76, 1000, BlockHash([0; 32]), true); + test_with_nu5_birthday_offset::(76, 1000, BlockHash([0; 32]), true).await; // Set up the following situation: // @@ -1019,18 +1021,18 @@ pub(crate) mod tests { assert_eq!(actual, expected); } - #[test] - fn sapling_update_chain_tip_unstable_max_scanned() { - update_chain_tip_unstable_max_scanned::(); + #[tokio::test] + async fn sapling_update_chain_tip_unstable_max_scanned() { + update_chain_tip_unstable_max_scanned::().await; } - #[test] + #[tokio::test] #[cfg(feature = "orchard")] - fn orchard_update_chain_tip_unstable_max_scanned() { - update_chain_tip_unstable_max_scanned::(); + async fn orchard_update_chain_tip_unstable_max_scanned() { + update_chain_tip_unstable_max_scanned::().await; } - fn update_chain_tip_unstable_max_scanned() { + async fn update_chain_tip_unstable_max_scanned() { use ScanPriority::*; // Set up the following situation: // @@ -1045,7 +1047,7 @@ pub(crate) mod tests { let frontier_tree_size: u32 = (0x1 << 16) + 1234; let mut st = TestBuilder::new() .with_data_store_factory(TestDbFactory::default()) - .with_block_cache(BlockCache::new()) + .with_block_cache(BlockCache::new().await) .with_initial_chain_state(|rng, network| { let birthday_height = network.activation_height(NetworkUpgrade::Nu5).unwrap() + birthday_offset; @@ -1134,8 +1136,9 @@ pub(crate) mod tests { frontier_tree_size + 10, frontier_tree_size + 10, false, - ); - st.scan_cached_blocks(max_scanned, 1); + ) + .await; + st.scan_cached_blocks(max_scanned, 1).await; // Verify that the suggested scan ranges match what is expected. let expected = vec![ @@ -1211,18 +1214,18 @@ pub(crate) mod tests { assert_eq!(actual, expected); } - #[test] - fn sapling_update_chain_tip_stable_max_scanned() { - update_chain_tip_stable_max_scanned::(); + #[tokio::test] + async fn sapling_update_chain_tip_stable_max_scanned() { + update_chain_tip_stable_max_scanned::().await; } - #[test] + #[tokio::test] #[cfg(feature = "orchard")] - fn orchard_update_chain_tip_stable_max_scanned() { - update_chain_tip_stable_max_scanned::(); + async fn orchard_update_chain_tip_stable_max_scanned() { + update_chain_tip_stable_max_scanned::().await; } - fn update_chain_tip_stable_max_scanned() { + async fn update_chain_tip_stable_max_scanned() { use ScanPriority::*; // Set up the following situation: @@ -1238,7 +1241,7 @@ pub(crate) mod tests { let frontier_tree_size: u32 = (0x1 << 16) + 1234; let mut st = TestBuilder::new() .with_data_store_factory(TestDbFactory::default()) - .with_block_cache(BlockCache::new()) + .with_block_cache(BlockCache::new().await) .with_initial_chain_state(|rng, network| { let birthday_height = network.activation_height(NetworkUpgrade::Nu5).unwrap() + birthday_offset; @@ -1338,8 +1341,9 @@ pub(crate) mod tests { frontier_tree_size + 10, frontier_tree_size + 10, false, - ); - st.scan_cached_blocks(max_scanned, 1); + ) + .await; + st.scan_cached_blocks(max_scanned, 1).await; // We have scanned a block, so we now have a starting tree position, 500 blocks above the // wallet birthday but before the end of the shard. @@ -1570,7 +1574,7 @@ pub(crate) mod tests { /// initialized such that the subtree root containing the wallet birthday has been inserted /// into the note commitment tree. #[cfg(feature = "orchard")] - fn prepare_orchard_block_spanning_test( + async fn prepare_orchard_block_spanning_test( with_birthday_subtree_root: bool, ) -> TestState { let birthday_nu5_offset = 5000; @@ -1580,7 +1584,7 @@ pub(crate) mod tests { let birthday_tree_size: u32 = (0x1 << 17) - 50; let mut st = TestBuilder::new() .with_data_store_factory(TestDbFactory::default()) - .with_block_cache(BlockCache::new()) + .with_block_cache(BlockCache::new().await) .with_initial_chain_state(|rng, network| { let birthday_height = network.activation_height(NetworkUpgrade::Nu5).unwrap() + birthday_nu5_offset; @@ -1643,28 +1647,33 @@ pub(crate) mod tests { let mut final_orchard_tree = birthday.orchard_frontier().clone(); // Generate the birthday block plus 10 more for _ in 0..11 { - let (_, res, _) = st.generate_next_block_multi(&vec![fake_output(false); 4]); + let (_, res, _) = st + .generate_next_block_multi(&vec![fake_output(false); 4]) + .await; for c in res.orchard() { final_orchard_tree.append(*c); } } // Generate a block with the last note in the block belonging to the wallet - let (_, res, _) = st.generate_next_block_multi(&vec![ - // 3 Orchard notes not for this wallet - fake_output(false), - fake_output(false), - fake_output(false), - // One Orchard note for this wallet - fake_output(true), - ]); + let (_, res, _) = st + .generate_next_block_multi(&vec![ + // 3 Orchard notes not for this wallet + fake_output(false), + fake_output(false), + fake_output(false), + // One Orchard note for this wallet + fake_output(true), + ]) + .await; for c in res.orchard() { final_orchard_tree.append(*c); } // Generate one block spanning the shard boundary - let (spanning_block_height, res, _) = - st.generate_next_block_multi(&vec![fake_output(false); 4]); + let (spanning_block_height, res, _) = st + .generate_next_block_multi(&vec![fake_output(false); 4]) + .await; // Add two note commitments to the Orchard frontier to complete the 2^16 subtree. We // can then add that subtree root to the Orchard frontier, so that we can compute the @@ -1697,7 +1706,9 @@ pub(crate) mod tests { // Add blocks up to the chain tip. let mut chain_tip_height = spanning_block_height; for _ in 0..110 { - let (h, res, _) = st.generate_next_block_multi(&vec![fake_output(false)]); + let (h, res, _) = st + .generate_next_block_multi(&vec![fake_output(false)]) + .await; for c in res.orchard() { final_orchard_tree.append(*c); } @@ -1710,12 +1721,12 @@ pub(crate) mod tests { st } - #[test] + #[tokio::test] #[cfg(feature = "orchard")] - fn orchard_block_spanning_tip_boundary_complete() { + async fn orchard_block_spanning_tip_boundary_complete() { use zcash_client_backend::data_api::Account as _; - let mut st = prepare_orchard_block_spanning_test(true); + let mut st = prepare_orchard_block_spanning_test(true).await; let account = st.test_account().cloned().unwrap(); let birthday = account.birthday(); @@ -1746,14 +1757,14 @@ pub(crate) mod tests { assert_eq!(actual, expected); // Scan the chain-tip range. - st.scan_cached_blocks(birthday.height() + 12, 112); + st.scan_cached_blocks(birthday.height() + 12, 112).await; // We haven't yet discovered our note, so balances should still be zero assert_eq!(st.get_total_balance(account.id()), NonNegativeAmount::ZERO); // Now scan the historic range; this should discover our note, which should now be // spendable. - st.scan_cached_blocks(birthday.height(), 12); + st.scan_cached_blocks(birthday.height(), 12).await; assert_eq!( st.get_total_balance(account.id()), NonNegativeAmount::const_from_u64(100000) @@ -1803,12 +1814,12 @@ pub(crate) mod tests { /// This test verifies that missing a single block that is required for computing a witness is /// sufficient to prevent witness construction. - #[test] + #[tokio::test] #[cfg(feature = "orchard")] - fn orchard_block_spanning_tip_boundary_incomplete() { + async fn orchard_block_spanning_tip_boundary_incomplete() { use zcash_client_backend::data_api::Account as _; - let mut st = prepare_orchard_block_spanning_test(false); + let mut st = prepare_orchard_block_spanning_test(false).await; let account = st.test_account().cloned().unwrap(); let birthday = account.birthday(); @@ -1835,14 +1846,14 @@ pub(crate) mod tests { assert_eq!(actual, expected); // Scan the chain-tip range, but omitting the spanning block. - st.scan_cached_blocks(birthday.height() + 13, 112); + st.scan_cached_blocks(birthday.height() + 13, 112).await; // We haven't yet discovered our note, so balances should still be zero assert_eq!(st.get_total_balance(account.id()), NonNegativeAmount::ZERO); // Now scan the historic range; this should discover our note but not // complete the tree. The note should not be considered spendable. - st.scan_cached_blocks(birthday.height(), 12); + st.scan_cached_blocks(birthday.height(), 12).await; assert_eq!( st.get_total_balance(account.id()), NonNegativeAmount::const_from_u64(100000) @@ -1883,7 +1894,7 @@ pub(crate) mod tests { assert_matches!(proposal, Err(_)); // Scan the missing block - st.scan_cached_blocks(birthday.height() + 12, 1); + st.scan_cached_blocks(birthday.height() + 12, 1).await; // Verify that it's now possible to create the proposal let proposal = st.propose_transfer( diff --git a/zcash_client_sqlite/src/wallet/transparent.rs b/zcash_client_sqlite/src/wallet/transparent.rs index b63848040..962b033d2 100644 --- a/zcash_client_sqlite/src/wallet/transparent.rs +++ b/zcash_client_sqlite/src/wallet/transparent.rs @@ -831,11 +831,12 @@ mod tests { ); } - #[test] - fn transparent_balance_across_shielding() { + #[tokio::test] + async fn transparent_balance_across_shielding() { zcash_client_backend::data_api::testing::transparent::transparent_balance_across_shielding( TestDbFactory::default(), - BlockCache::new(), - ); + BlockCache::new().await, + ) + .await; } }