Merge pull request #915 from nuttycom/sbs/pre_birthday_test_refactor

Test refactorings in preparation for #907
This commit is contained in:
str4d 2023-08-30 00:44:41 +01:00 committed by GitHub
commit 31e5a5188e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 281 additions and 271 deletions

View File

@ -11,6 +11,7 @@ and this library adheres to Rust's notion of
- `impl Eq for zcash_client_backend::zip321::{Payment, TransactionRequest}` - `impl Eq for zcash_client_backend::zip321::{Payment, TransactionRequest}`
- `impl Debug` for `zcash_client_backend::{data_api::wallet::input_selection::Proposal, wallet::ReceivedSaplingNote}` - `impl Debug` for `zcash_client_backend::{data_api::wallet::input_selection::Proposal, wallet::ReceivedSaplingNote}`
- `zcash_client_backend::data_api`: - `zcash_client_backend::data_api`:
- `AccountBirthday`
- `BlockMetadata` - `BlockMetadata`
- `NoteId` - `NoteId`
- `NullifierQuery` for use with `WalletRead::get_sapling_nullifiers` - `NullifierQuery` for use with `WalletRead::get_sapling_nullifiers`
@ -28,6 +29,8 @@ and this library adheres to Rust's notion of
- `ScanError` - `ScanError`
- `impl<K: ScanningKey> ScanningKey for &K` - `impl<K: ScanningKey> ScanningKey for &K`
- `impl ScanningKey for (zip32::Scope, sapling::SaplingIvk, sapling::NullifierDerivingKey)` - `impl ScanningKey for (zip32::Scope, sapling::SaplingIvk, sapling::NullifierDerivingKey)`
- Test utility functions `zcash_client_backend::keys::UnifiedSpendingKey::{default_address,
default_transparent_address}` are now available under the `test-dependencies` feature flag.
### Changed ### Changed
- MSRV is now 1.65.0. - MSRV is now 1.65.0.

View File

@ -4,7 +4,7 @@ use std::collections::HashMap;
use std::fmt::Debug; use std::fmt::Debug;
use std::num::NonZeroU32; use std::num::NonZeroU32;
use incrementalmerkletree::Retention; use incrementalmerkletree::{frontier::Frontier, Retention};
use secrecy::SecretVec; use secrecy::SecretVec;
use shardtree::{error::ShardTreeError, store::ShardStore, ShardTree}; use shardtree::{error::ShardTreeError, store::ShardStore, ShardTree};
use zcash_primitives::{ use zcash_primitives::{
@ -12,7 +12,7 @@ use zcash_primitives::{
consensus::BlockHeight, consensus::BlockHeight,
legacy::TransparentAddress, legacy::TransparentAddress,
memo::{Memo, MemoBytes}, memo::{Memo, MemoBytes},
sapling, sapling::{self, Node, NOTE_COMMITMENT_TREE_DEPTH},
transaction::{ transaction::{
components::{amount::Amount, OutPoint}, components::{amount::Amount, OutPoint},
Transaction, TxId, Transaction, TxId,
@ -466,6 +466,43 @@ impl SentTransactionOutput {
} }
} }
/// A data structure used to set the birthday height for an account, and ensure that the initial
/// note commitment tree state is recorded at that height.
#[derive(Clone, Debug)]
pub struct AccountBirthday {
height: BlockHeight,
sapling_frontier: Frontier<Node, NOTE_COMMITMENT_TREE_DEPTH>,
}
impl AccountBirthday {
/// Constructs a new [`AccountBirthday`] from its constituent parts.
///
/// * `height`: The birthday height of the account. This is defined as the height of the last
/// block that is known to contain no transactions sent to addresses belonging to the account.
/// * `sapling_frontier`: The Sapling note commitment tree frontier as of the end of the block
/// at `height`.
pub fn from_parts(
height: BlockHeight,
sapling_frontier: Frontier<Node, NOTE_COMMITMENT_TREE_DEPTH>,
) -> Self {
Self {
height,
sapling_frontier,
}
}
/// Returns the Sapling note commitment tree frontier as of the end of the block at
/// [`Self::height`].
pub fn sapling_frontier(&self) -> &Frontier<Node, NOTE_COMMITMENT_TREE_DEPTH> {
&self.sapling_frontier
}
/// Returns the birthday height of the account.
pub fn height(&self) -> BlockHeight {
self.height
}
}
/// This trait encapsulates the write capabilities required to update stored /// This trait encapsulates the write capabilities required to update stored
/// wallet data. /// wallet data.
pub trait WalletWrite: WalletRead { pub trait WalletWrite: WalletRead {

View File

@ -14,6 +14,9 @@ use {
zcash_primitives::legacy::keys::{self as legacy, IncomingViewingKey}, zcash_primitives::legacy::keys::{self as legacy, IncomingViewingKey},
}; };
#[cfg(all(feature = "test-dependencies", feature = "transparent-inputs"))]
use zcash_primitives::legacy::TransparentAddress;
#[cfg(feature = "unstable")] #[cfg(feature = "unstable")]
use { use {
byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}, byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt},
@ -336,6 +339,20 @@ impl UnifiedSpendingKey {
} }
} }
} }
#[cfg(feature = "test-dependencies")]
pub fn default_address(&self) -> (UnifiedAddress, DiversifierIndex) {
self.to_unified_full_viewing_key().default_address()
}
#[cfg(all(feature = "test-dependencies", feature = "transparent-inputs"))]
pub fn default_transparent_address(&self) -> (TransparentAddress, u32) {
self.transparent()
.to_account_pubkey()
.derive_external_ivk()
.unwrap()
.default_address()
}
} }
/// A [ZIP 316](https://zips.z.cash/zip-0316) unified full viewing key. /// A [ZIP 316](https://zips.z.cash/zip-0316) unified full viewing key.

View File

@ -60,6 +60,7 @@ tempfile = "3.5.0"
zcash_note_encryption = "0.4" zcash_note_encryption = "0.4"
zcash_proofs = { version = "0.12", path = "../zcash_proofs" } zcash_proofs = { version = "0.12", path = "../zcash_proofs" }
zcash_primitives = { version = "0.12", path = "../zcash_primitives", features = ["test-dependencies"] } zcash_primitives = { version = "0.12", path = "../zcash_primitives", features = ["test-dependencies"] }
zcash_client_backend = { version = "0.9", path = "../zcash_client_backend", features = ["test-dependencies"] }
zcash_address = { version = "0.3", path = "../components/zcash_address", features = ["test-dependencies"] } zcash_address = { version = "0.3", path = "../components/zcash_address", features = ["test-dependencies"] }
[features] [features]

View File

@ -345,7 +345,7 @@ mod tests {
}; };
use crate::{ use crate::{
testing::{AddressType, TestBuilder}, testing::{birthday_at_sapling_activation, AddressType, TestBuilder},
wallet::{get_balance, truncate_to_height}, wallet::{get_balance, truncate_to_height},
AccountId, AccountId,
}; };
@ -354,8 +354,7 @@ mod tests {
fn valid_chain_states() { fn valid_chain_states() {
let mut st = TestBuilder::new() let mut st = TestBuilder::new()
.with_block_cache() .with_block_cache()
.with_seed(Secret::new(vec![])) .with_test_account(birthday_at_sapling_activation)
.with_test_account()
.build(); .build();
let dfvk = st.test_account_sapling().unwrap(); let dfvk = st.test_account_sapling().unwrap();
@ -388,8 +387,7 @@ mod tests {
fn invalid_chain_cache_disconnected() { fn invalid_chain_cache_disconnected() {
let mut st = TestBuilder::new() let mut st = TestBuilder::new()
.with_block_cache() .with_block_cache()
.with_seed(Secret::new(vec![])) .with_test_account(birthday_at_sapling_activation)
.with_test_account()
.build(); .build();
let dfvk = st.test_account_sapling().unwrap(); let dfvk = st.test_account_sapling().unwrap();
@ -440,8 +438,7 @@ mod tests {
fn data_db_truncation() { fn data_db_truncation() {
let mut st = TestBuilder::new() let mut st = TestBuilder::new()
.with_block_cache() .with_block_cache()
.with_seed(Secret::new(vec![])) .with_test_account(birthday_at_sapling_activation)
.with_test_account()
.build(); .build();
let dfvk = st.test_account_sapling().unwrap(); let dfvk = st.test_account_sapling().unwrap();
@ -501,10 +498,7 @@ mod tests {
#[test] #[test]
fn scan_cached_blocks_allows_blocks_out_of_order() { fn scan_cached_blocks_allows_blocks_out_of_order() {
let mut st = TestBuilder::new() let mut st = TestBuilder::new().with_block_cache().build();
.with_block_cache()
.with_seed(Secret::new(vec![]))
.build();
// Add an account to the wallet // Add an account to the wallet
let seed = Secret::new([0u8; 32].to_vec()); let seed = Secret::new([0u8; 32].to_vec());
@ -564,8 +558,7 @@ mod tests {
fn scan_cached_blocks_finds_received_notes() { fn scan_cached_blocks_finds_received_notes() {
let mut st = TestBuilder::new() let mut st = TestBuilder::new()
.with_block_cache() .with_block_cache()
.with_seed(Secret::new(vec![])) .with_test_account(birthday_at_sapling_activation)
.with_test_account()
.build(); .build();
let dfvk = st.test_account_sapling().unwrap(); let dfvk = st.test_account_sapling().unwrap();
@ -607,8 +600,7 @@ mod tests {
fn scan_cached_blocks_finds_change_notes() { fn scan_cached_blocks_finds_change_notes() {
let mut st = TestBuilder::new() let mut st = TestBuilder::new()
.with_block_cache() .with_block_cache()
.with_seed(Secret::new(vec![])) .with_test_account(birthday_at_sapling_activation)
.with_test_account()
.build(); .build();
let dfvk = st.test_account_sapling().unwrap(); let dfvk = st.test_account_sapling().unwrap();
@ -653,8 +645,7 @@ mod tests {
fn scan_cached_blocks_detects_spends_out_of_order() { fn scan_cached_blocks_detects_spends_out_of_order() {
let mut st = TestBuilder::new() let mut st = TestBuilder::new()
.with_block_cache() .with_block_cache()
.with_seed(Secret::new(vec![])) .with_test_account(birthday_at_sapling_activation)
.with_test_account()
.build(); .build();
let dfvk = st.test_account_sapling().unwrap(); let dfvk = st.test_account_sapling().unwrap();

View File

@ -1087,7 +1087,10 @@ extern crate assert_matches;
mod tests { mod tests {
use zcash_client_backend::data_api::{WalletRead, WalletWrite}; use zcash_client_backend::data_api::{WalletRead, WalletWrite};
use crate::{testing::TestBuilder, AccountId}; use crate::{
testing::{birthday_at_sapling_activation, TestBuilder},
AccountId,
};
#[cfg(feature = "unstable")] #[cfg(feature = "unstable")]
use zcash_primitives::{consensus::Parameters, transaction::components::Amount}; use zcash_primitives::{consensus::Parameters, transaction::components::Amount};
@ -1100,7 +1103,9 @@ mod tests {
#[test] #[test]
pub(crate) fn get_next_available_address() { pub(crate) fn get_next_available_address() {
let mut st = TestBuilder::new().with_test_account().build(); let mut st = TestBuilder::new()
.with_test_account(birthday_at_sapling_activation)
.build();
let account = AccountId::from(0); let account = AccountId::from(0);
let current_addr = st.wallet().get_current_address(account).unwrap(); let current_addr = st.wallet().get_current_address(account).unwrap();
@ -1117,17 +1122,15 @@ mod tests {
#[cfg(feature = "transparent-inputs")] #[cfg(feature = "transparent-inputs")]
#[test] #[test]
fn transparent_receivers() { fn transparent_receivers() {
use secrecy::Secret; // Add an account to the wallet.
let st = TestBuilder::new() let st = TestBuilder::new()
.with_block_cache() .with_block_cache()
.with_seed(Secret::new(vec![])) .with_test_account(birthday_at_sapling_activation)
.with_test_account()
.build(); .build();
// Add an account to the wallet. let (_, usk, _) = st.test_account().unwrap();
let (ufvk, taddr) = st.test_account().unwrap(); let ufvk = usk.to_unified_full_viewing_key();
let taddr = taddr.unwrap(); let (taddr, _) = usk.default_transparent_address();
let receivers = st.wallet().get_transparent_receivers(0.into()).unwrap(); let receivers = st.wallet().get_transparent_receivers(0.into()).unwrap();

View File

@ -1,6 +1,6 @@
use std::convert::Infallible; use std::convert::Infallible;
use std::fmt; use std::fmt;
use std::{collections::HashMap, num::NonZeroU32}; use std::num::NonZeroU32;
#[cfg(feature = "unstable")] #[cfg(feature = "unstable")]
use std::fs::File; use std::fs::File;
@ -8,26 +8,26 @@ use std::fs::File;
use prost::Message; use prost::Message;
use rand_core::{OsRng, RngCore}; use rand_core::{OsRng, RngCore};
use rusqlite::{params, Connection}; use rusqlite::{params, Connection};
use secrecy::SecretVec; use secrecy::Secret;
use tempfile::NamedTempFile; use tempfile::NamedTempFile;
#[cfg(feature = "unstable")] #[cfg(feature = "unstable")]
use tempfile::TempDir; use tempfile::TempDir;
#[allow(deprecated)] #[allow(deprecated)]
use zcash_client_backend::data_api::wallet::create_spend_to_address;
use zcash_client_backend::{ use zcash_client_backend::{
address::RecipientAddress, address::RecipientAddress,
data_api::{ data_api::{
self, self,
chain::{scan_cached_blocks, BlockSource}, chain::{scan_cached_blocks, BlockSource},
wallet::{ wallet::{
create_proposed_transaction, create_proposed_transaction, create_spend_to_address,
input_selection::{GreedyInputSelectorError, InputSelector, Proposal}, input_selection::{GreedyInputSelectorError, InputSelector, Proposal},
propose_transfer, spend, propose_transfer, spend,
}, },
AccountBirthday, WalletWrite,
}, },
keys::{sapling, UnifiedFullViewingKey, UnifiedSpendingKey}, keys::UnifiedSpendingKey,
proto::compact_formats::{ proto::compact_formats::{
self as compact, CompactBlock, CompactSaplingOutput, CompactSaplingSpend, CompactTx, self as compact, CompactBlock, CompactSaplingOutput, CompactSaplingSpend, CompactTx,
}, },
@ -37,7 +37,7 @@ use zcash_client_backend::{
use zcash_note_encryption::Domain; use zcash_note_encryption::Domain;
use zcash_primitives::{ use zcash_primitives::{
block::BlockHash, block::BlockHash,
consensus::{BlockHeight, Network, NetworkUpgrade, Parameters}, consensus::{self, BlockHeight, Network, NetworkUpgrade, Parameters},
legacy::TransparentAddress, legacy::TransparentAddress,
memo::MemoBytes, memo::MemoBytes,
sapling::{ sapling::{
@ -54,54 +54,50 @@ use zcash_primitives::{
zip32::{sapling::DiversifiableFullViewingKey, DiversifierIndex}, zip32::{sapling::DiversifiableFullViewingKey, DiversifierIndex},
}; };
#[cfg(feature = "transparent-inputs")]
use zcash_client_backend::data_api::wallet::{propose_shielding, shield_transparent_funds};
#[cfg(feature = "transparent-inputs")]
use zcash_primitives::{
legacy, legacy::keys::IncomingViewingKey, transaction::components::amount::NonNegativeAmount,
};
use crate::{ use crate::{
chain::init::init_cache_database, chain::init::init_cache_database,
error::SqliteClientError, error::SqliteClientError,
wallet::{ wallet::{commitment_tree, init::init_wallet_db, sapling::tests::test_prover},
commitment_tree,
init::{init_accounts_table, init_wallet_db},
sapling::tests::test_prover,
},
AccountId, ReceivedNoteId, WalletDb, AccountId, ReceivedNoteId, WalletDb,
}; };
use super::BlockDb; use super::BlockDb;
#[cfg(feature = "transparent-inputs")]
use {
zcash_client_backend::data_api::wallet::{propose_shielding, shield_transparent_funds},
zcash_primitives::transaction::components::amount::NonNegativeAmount,
};
#[cfg(feature = "unstable")] #[cfg(feature = "unstable")]
use crate::{ use crate::{
chain::{init::init_blockmeta_db, BlockMeta}, chain::{init::init_blockmeta_db, BlockMeta},
FsBlockDb, FsBlockDb,
}; };
/// A builder for a `zcash_client_sqlite` test. /// A builder for a `zcash_client_sqlite` test.
pub(crate) struct TestBuilder<Cache> { pub(crate) struct TestBuilder<Cache> {
network: Network,
cache: Cache, cache: Cache,
seed: Option<SecretVec<u8>>, test_account_birthday: Option<AccountBirthday>,
with_test_account: bool,
} }
impl TestBuilder<()> { impl TestBuilder<()> {
/// Constructs a new test. /// Constructs a new test.
pub(crate) fn new() -> Self { pub(crate) fn new() -> Self {
TestBuilder { TestBuilder {
network: Network::TestNetwork,
cache: (), cache: (),
seed: None, test_account_birthday: None,
with_test_account: false,
} }
} }
/// Adds a [`BlockDb`] cache to the test. /// Adds a [`BlockDb`] cache to the test.
pub(crate) fn with_block_cache(self) -> TestBuilder<BlockCache> { pub(crate) fn with_block_cache(self) -> TestBuilder<BlockCache> {
TestBuilder { TestBuilder {
network: self.network,
cache: BlockCache::new(), cache: BlockCache::new(),
seed: self.seed, test_account_birthday: self.test_account_birthday,
with_test_account: self.with_test_account,
} }
} }
@ -109,43 +105,37 @@ impl TestBuilder<()> {
#[cfg(feature = "unstable")] #[cfg(feature = "unstable")]
pub(crate) fn with_fs_block_cache(self) -> TestBuilder<FsBlockCache> { pub(crate) fn with_fs_block_cache(self) -> TestBuilder<FsBlockCache> {
TestBuilder { TestBuilder {
network: self.network,
cache: FsBlockCache::new(), cache: FsBlockCache::new(),
seed: self.seed, test_account_birthday: self.test_account_birthday,
with_test_account: self.with_test_account,
} }
} }
} }
impl<Cache> TestBuilder<Cache> { impl<Cache> TestBuilder<Cache> {
/// Gives the test knowledge of the wallet seed for initialization. pub(crate) fn with_test_account<F: FnOnce(&Network) -> AccountBirthday>(
pub(crate) fn with_seed(mut self, seed: SecretVec<u8>) -> Self { mut self,
// TODO remove birthday: F,
self.seed = Some(seed); ) -> Self {
self self.test_account_birthday = Some(birthday(&self.network));
}
pub(crate) fn with_test_account(mut self) -> Self {
self.with_test_account = true;
self self
} }
/// Builds the state for this test. /// Builds the state for this test.
pub(crate) fn build(self) -> TestState<Cache> { pub(crate) fn build(self) -> TestState<Cache> {
let params = network();
let data_file = NamedTempFile::new().unwrap(); let data_file = NamedTempFile::new().unwrap();
let mut db_data = WalletDb::for_path(data_file.path(), params).unwrap(); let mut db_data = WalletDb::for_path(data_file.path(), self.network).unwrap();
init_wallet_db(&mut db_data, self.seed).unwrap(); init_wallet_db(&mut db_data, None).unwrap();
let test_account = if self.with_test_account { let test_account = if let Some(birthday) = self.test_account_birthday {
// Add an account to the wallet let seed = Secret::new(vec![0u8; 32]);
Some(init_test_accounts_table_ufvk(&mut db_data)) let (account, usk) = db_data.create_account(&seed).unwrap();
Some((account, usk, birthday))
} else { } else {
None None
}; };
TestState { TestState {
params,
cache: self.cache, cache: self.cache,
latest_cached_block: None, latest_cached_block: None,
_data_file: data_file, _data_file: data_file,
@ -157,12 +147,11 @@ impl<Cache> TestBuilder<Cache> {
/// The state for a `zcash_client_sqlite` test. /// The state for a `zcash_client_sqlite` test.
pub(crate) struct TestState<Cache> { pub(crate) struct TestState<Cache> {
params: Network,
cache: Cache, cache: Cache,
latest_cached_block: Option<(BlockHeight, BlockHash, u32)>, latest_cached_block: Option<(BlockHeight, BlockHash, u32)>,
_data_file: NamedTempFile, _data_file: NamedTempFile,
db_data: WalletDb<Connection, Network>, db_data: WalletDb<Connection, Network>,
test_account: Option<(UnifiedFullViewingKey, Option<TransparentAddress>)>, test_account: Option<(AccountId, UnifiedSpendingKey, AccountBirthday)>,
} }
impl<Cache: TestCache> TestState<Cache> impl<Cache: TestCache> TestState<Cache>
@ -186,7 +175,7 @@ where
let (height, prev_hash, initial_sapling_tree_size) = self let (height, prev_hash, initial_sapling_tree_size) = self
.latest_cached_block .latest_cached_block
.map(|(prev_height, prev_hash, end_size)| (prev_height + 1, prev_hash, end_size)) .map(|(prev_height, prev_hash, end_size)| (prev_height + 1, prev_hash, end_size))
.unwrap_or_else(|| (sapling_activation_height(), BlockHash([0; 32]), 0)); .unwrap_or_else(|| (self.sapling_activation_height(), BlockHash([0; 32]), 0));
let (res, nf) = self.generate_block_at( let (res, nf) = self.generate_block_at(
height, height,
@ -215,6 +204,7 @@ where
initial_sapling_tree_size: u32, initial_sapling_tree_size: u32,
) -> (Cache::InsertResult, Nullifier) { ) -> (Cache::InsertResult, Nullifier) {
let (cb, nf) = fake_compact_block( let (cb, nf) = fake_compact_block(
&self.network(),
height, height,
prev_hash, prev_hash,
dfvk, dfvk,
@ -246,9 +236,10 @@ where
let (height, prev_hash, initial_sapling_tree_size) = self let (height, prev_hash, initial_sapling_tree_size) = self
.latest_cached_block .latest_cached_block
.map(|(prev_height, prev_hash, end_size)| (prev_height + 1, prev_hash, end_size)) .map(|(prev_height, prev_hash, end_size)| (prev_height + 1, prev_hash, end_size))
.unwrap_or_else(|| (sapling_activation_height(), BlockHash([0; 32]), 0)); .unwrap_or_else(|| (self.sapling_activation_height(), BlockHash([0; 32]), 0));
let cb = fake_compact_block_spending( let cb = fake_compact_block_spending(
&self.network(),
height, height,
prev_hash, prev_hash,
note, note,
@ -271,8 +262,7 @@ where
/// Invokes [`scan_cached_blocks`] with the given arguments, expecting success. /// Invokes [`scan_cached_blocks`] with the given arguments, expecting success.
pub(crate) fn scan_cached_blocks(&mut self, from_height: BlockHeight, limit: usize) { pub(crate) fn scan_cached_blocks(&mut self, from_height: BlockHeight, limit: usize) {
self.try_scan_cached_blocks(from_height, limit) assert_matches!(self.try_scan_cached_blocks(from_height, limit), Ok(_));
.expect("should succeed for this test");
} }
/// Invokes [`scan_cached_blocks`] with the given arguments. /// Invokes [`scan_cached_blocks`] with the given arguments.
@ -288,7 +278,7 @@ where
>, >,
> { > {
scan_cached_blocks( scan_cached_blocks(
&self.params, &self.network(),
self.cache.block_source(), self.cache.block_source(),
&mut self.db_data, &mut self.db_data,
from_height, from_height,
@ -308,11 +298,21 @@ impl<Cache> TestState<Cache> {
&mut self.db_data &mut self.db_data
} }
/// Exposes the network in use.
pub(crate) fn network(&self) -> Network {
self.db_data.params
}
/// Convenience method for obtaining the Sapling activation height for the network under test.
pub(crate) fn sapling_activation_height(&self) -> BlockHeight {
self.db_data
.params
.activation_height(NetworkUpgrade::Sapling)
.expect("Sapling activation height must be known.")
}
/// Exposes the test account, if enabled via [`TestBuilder::with_test_account`]. /// Exposes the test account, if enabled via [`TestBuilder::with_test_account`].
#[cfg(feature = "unstable")] pub(crate) fn test_account(&self) -> Option<(AccountId, UnifiedSpendingKey, AccountBirthday)> {
pub(crate) fn test_account(
&self,
) -> Option<(UnifiedFullViewingKey, Option<TransparentAddress>)> {
self.test_account.as_ref().cloned() self.test_account.as_ref().cloned()
} }
@ -320,7 +320,7 @@ impl<Cache> TestState<Cache> {
pub(crate) fn test_account_sapling(&self) -> Option<DiversifiableFullViewingKey> { pub(crate) fn test_account_sapling(&self) -> Option<DiversifiableFullViewingKey> {
self.test_account self.test_account
.as_ref() .as_ref()
.map(|(ufvk, _)| ufvk.sapling().unwrap().clone()) .and_then(|(_, usk, _)| usk.to_unified_full_viewing_key().sapling().cloned())
} }
/// Invokes [`create_spend_to_address`] with the given arguments. /// Invokes [`create_spend_to_address`] with the given arguments.
@ -344,9 +344,10 @@ impl<Cache> TestState<Cache> {
ReceivedNoteId, ReceivedNoteId,
>, >,
> { > {
let params = self.network();
create_spend_to_address( create_spend_to_address(
&mut self.db_data, &mut self.db_data,
&self.params, &params,
test_prover(), test_prover(),
usk, usk,
to, to,
@ -379,9 +380,10 @@ impl<Cache> TestState<Cache> {
where where
InputsT: InputSelector<DataSource = WalletDb<Connection, Network>>, InputsT: InputSelector<DataSource = WalletDb<Connection, Network>>,
{ {
let params = self.network();
spend( spend(
&mut self.db_data, &mut self.db_data,
&self.params, &params,
test_prover(), test_prover(),
input_selector, input_selector,
usk, usk,
@ -412,9 +414,10 @@ impl<Cache> TestState<Cache> {
where where
InputsT: InputSelector<DataSource = WalletDb<Connection, Network>>, InputsT: InputSelector<DataSource = WalletDb<Connection, Network>>,
{ {
let params = self.network();
propose_transfer::<_, _, _, Infallible>( propose_transfer::<_, _, _, Infallible>(
&mut self.db_data, &mut self.db_data,
&self.params, &params,
spend_from_account, spend_from_account,
input_selector, input_selector,
request, request,
@ -444,9 +447,10 @@ impl<Cache> TestState<Cache> {
where where
InputsT: InputSelector<DataSource = WalletDb<Connection, Network>>, InputsT: InputSelector<DataSource = WalletDb<Connection, Network>>,
{ {
let params = self.network();
propose_shielding::<_, _, _, Infallible>( propose_shielding::<_, _, _, Infallible>(
&mut self.db_data, &mut self.db_data,
&self.params, &params,
input_selector, input_selector,
shielding_threshold, shielding_threshold,
from_addrs, from_addrs,
@ -475,9 +479,10 @@ impl<Cache> TestState<Cache> {
where where
FeeRuleT: FeeRule, FeeRuleT: FeeRule,
{ {
let params = self.network();
create_proposed_transaction::<_, _, Infallible, _>( create_proposed_transaction::<_, _, Infallible, _>(
&mut self.db_data, &mut self.db_data,
&self.params, &params,
test_prover(), test_prover(),
usk, usk,
ovk_policy, ovk_policy,
@ -511,9 +516,10 @@ impl<Cache> TestState<Cache> {
where where
InputsT: InputSelector<DataSource = WalletDb<Connection, Network>>, InputsT: InputSelector<DataSource = WalletDb<Connection, Network>>,
{ {
let params = self.network();
shield_transparent_funds( shield_transparent_funds(
&mut self.db_data, &mut self.db_data,
&self.params, &params,
test_prover(), test_prover(),
input_selector, input_selector,
shielding_threshold, shielding_threshold,
@ -525,63 +531,15 @@ impl<Cache> TestState<Cache> {
} }
} }
#[cfg(feature = "mainnet")]
pub(crate) fn network() -> Network {
Network::MainNetwork
}
#[cfg(not(feature = "mainnet"))]
pub(crate) fn network() -> Network {
Network::TestNetwork
}
#[cfg(feature = "mainnet")]
pub(crate) fn sapling_activation_height() -> BlockHeight {
Network::MainNetwork
.activation_height(NetworkUpgrade::Sapling)
.unwrap()
}
#[cfg(not(feature = "mainnet"))]
pub(crate) fn sapling_activation_height() -> BlockHeight {
Network::TestNetwork
.activation_height(NetworkUpgrade::Sapling)
.unwrap()
}
#[cfg(test)] #[cfg(test)]
pub(crate) fn init_test_accounts_table_ufvk( pub(crate) fn birthday_at_sapling_activation<P: consensus::Parameters>(
db_data: &mut WalletDb<rusqlite::Connection, Network>, params: &P,
) -> (UnifiedFullViewingKey, Option<TransparentAddress>) { ) -> AccountBirthday {
let seed = [0u8; 32]; use incrementalmerkletree::frontier::Frontier;
let account = AccountId::from(0); AccountBirthday::from_parts(
let extsk = sapling::spending_key(&seed, network().coin_type(), account); params.activation_height(NetworkUpgrade::Sapling).unwrap(),
let dfvk = extsk.to_diversifiable_full_viewing_key(); Frontier::empty(),
#[cfg(feature = "transparent-inputs")]
let (tkey, taddr) = {
let tkey = legacy::keys::AccountPrivKey::from_seed(&network(), &seed, account)
.unwrap()
.to_account_pubkey();
let taddr = tkey.derive_external_ivk().unwrap().default_address().0;
(Some(tkey), Some(taddr))
};
#[cfg(not(feature = "transparent-inputs"))]
let taddr = None;
let ufvk = UnifiedFullViewingKey::new(
#[cfg(feature = "transparent-inputs")]
tkey,
Some(dfvk),
None,
) )
.unwrap();
let ufvks = HashMap::from([(account, ufvk.clone())]);
init_accounts_table(db_data, &ufvks).unwrap();
(ufvk, taddr)
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -593,7 +551,8 @@ pub(crate) enum AddressType {
/// Create a fake CompactBlock at the given height, containing a single output paying /// Create a fake CompactBlock at the given height, containing a single output paying
/// an address. Returns the CompactBlock and the nullifier for the new note. /// an address. Returns the CompactBlock and the nullifier for the new note.
pub(crate) fn fake_compact_block( pub(crate) fn fake_compact_block<P: consensus::Parameters>(
params: &P,
height: BlockHeight, height: BlockHeight,
prev_hash: BlockHash, prev_hash: BlockHash,
dfvk: &DiversifiableFullViewingKey, dfvk: &DiversifiableFullViewingKey,
@ -609,7 +568,7 @@ pub(crate) fn fake_compact_block(
// Create a fake Note for the account // Create a fake Note for the account
let mut rng = OsRng; let mut rng = OsRng;
let rseed = generate_random_rseed(&network(), height, &mut rng); let rseed = generate_random_rseed(params, height, &mut rng);
let note = Note::from_parts(to, NoteValue::from_raw(value.into()), rseed); let note = Note::from_parts(to, NoteValue::from_raw(value.into()), rseed);
let encryptor = sapling_note_encryption::<_, Network>( let encryptor = sapling_note_encryption::<_, Network>(
Some(dfvk.fvk().ovk), Some(dfvk.fvk().ovk),
@ -655,7 +614,9 @@ pub(crate) fn fake_compact_block(
/// Create a fake CompactBlock at the given height, spending a single note from the /// Create a fake CompactBlock at the given height, spending a single note from the
/// given address. /// given address.
pub(crate) fn fake_compact_block_spending( #[allow(clippy::too_many_arguments)]
pub(crate) fn fake_compact_block_spending<P: consensus::Parameters>(
params: &P,
height: BlockHeight, height: BlockHeight,
prev_hash: BlockHash, prev_hash: BlockHash,
(nf, in_value): (Nullifier, Amount), (nf, in_value): (Nullifier, Amount),
@ -665,7 +626,7 @@ pub(crate) fn fake_compact_block_spending(
initial_sapling_tree_size: u32, initial_sapling_tree_size: u32,
) -> CompactBlock { ) -> CompactBlock {
let mut rng = OsRng; let mut rng = OsRng;
let rseed = generate_random_rseed(&network(), height, &mut rng); let rseed = generate_random_rseed(params, height, &mut rng);
// Create a fake CompactBlock containing the note // Create a fake CompactBlock containing the note
let cspend = CompactSaplingSpend { nf: nf.to_vec() }; let cspend = CompactSaplingSpend { nf: nf.to_vec() };
@ -700,7 +661,7 @@ pub(crate) fn fake_compact_block_spending(
// Create a fake Note for the change // Create a fake Note for the change
ctx.outputs.push({ ctx.outputs.push({
let change_addr = dfvk.default_address().1; let change_addr = dfvk.default_address().1;
let rseed = generate_random_rseed(&network(), height, &mut rng); let rseed = generate_random_rseed(params, height, &mut rng);
let note = Note::from_parts( let note = Note::from_parts(
change_addr, change_addr,
NoteValue::from_raw((in_value - value).unwrap().into()), NoteValue::from_raw((in_value - value).unwrap().into()),

View File

@ -1577,7 +1577,10 @@ mod tests {
use zcash_client_backend::data_api::WalletRead; use zcash_client_backend::data_api::WalletRead;
use crate::{testing::TestBuilder, AccountId}; use crate::{
testing::{birthday_at_sapling_activation, TestBuilder},
AccountId,
};
use super::get_balance; use super::get_balance;
@ -1595,8 +1598,7 @@ mod tests {
#[test] #[test]
fn empty_database_has_no_balance() { fn empty_database_has_no_balance() {
let st = TestBuilder::new() let st = TestBuilder::new()
.with_seed(Secret::new(vec![])) .with_test_account(birthday_at_sapling_activation)
.with_test_account()
.build(); .build();
// The account should be empty // The account should be empty

View File

@ -985,14 +985,14 @@ mod tests {
}; };
use shardtree::ShardTree; use shardtree::ShardTree;
use zcash_client_backend::data_api::chain::CommitmentTreeRoot; use zcash_client_backend::data_api::chain::CommitmentTreeRoot;
use zcash_primitives::consensus::BlockHeight; use zcash_primitives::consensus::{BlockHeight, Network};
use super::SqliteShardStore; use super::SqliteShardStore;
use crate::{testing, wallet::init::init_wallet_db, WalletDb, SAPLING_TABLES_PREFIX}; use crate::{wallet::init::init_wallet_db, WalletDb, SAPLING_TABLES_PREFIX};
fn new_tree(m: usize) -> ShardTree<SqliteShardStore<rusqlite::Connection, String, 3>, 4, 3> { fn new_tree(m: usize) -> ShardTree<SqliteShardStore<rusqlite::Connection, String, 3>, 4, 3> {
let data_file = NamedTempFile::new().unwrap(); let data_file = NamedTempFile::new().unwrap();
let mut db_data = WalletDb::for_path(data_file.path(), testing::network()).unwrap(); let mut db_data = WalletDb::for_path(data_file.path(), Network::TestNetwork).unwrap();
data_file.keep().unwrap(); data_file.keep().unwrap();
init_wallet_db(&mut db_data, None).unwrap(); init_wallet_db(&mut db_data, None).unwrap();
@ -1040,7 +1040,7 @@ mod tests {
#[test] #[test]
fn put_shard_roots() { fn put_shard_roots() {
let data_file = NamedTempFile::new().unwrap(); let data_file = NamedTempFile::new().unwrap();
let mut db_data = WalletDb::for_path(data_file.path(), testing::network()).unwrap(); let mut db_data = WalletDb::for_path(data_file.path(), Network::TestNetwork).unwrap();
data_file.keep().unwrap(); data_file.keep().unwrap();
init_wallet_db(&mut db_data, None).unwrap(); init_wallet_db(&mut db_data, None).unwrap();

View File

@ -386,37 +386,29 @@ mod tests {
use zcash_primitives::{ use zcash_primitives::{
block::BlockHash, block::BlockHash,
consensus::{BlockHeight, BranchId, NetworkUpgrade, Parameters}, consensus::{self, BlockHeight, BranchId, Network, NetworkUpgrade, Parameters},
transaction::{TransactionData, TxVersion}, transaction::{TransactionData, TxVersion},
zip32::sapling::ExtendedFullViewingKey, zip32::sapling::ExtendedFullViewingKey,
}; };
use crate::{ use crate::{
error::SqliteClientError, error::SqliteClientError, testing::TestBuilder, wallet::scanning::priority_code, AccountId,
testing::{self, network}, WalletDb,
wallet::scanning::priority_code,
AccountId, WalletDb,
}; };
use super::{init_accounts_table, init_blocks_table, init_wallet_db}; use super::{init_accounts_table, init_blocks_table, init_wallet_db};
#[cfg(feature = "transparent-inputs")] #[cfg(feature = "transparent-inputs")]
use { use {
crate::{ crate::wallet::{self, pool_code, PoolType},
wallet::{self, pool_code, PoolType},
WalletWrite,
},
zcash_address::test_vectors, zcash_address::test_vectors,
zcash_primitives::{ zcash_client_backend::data_api::WalletWrite,
consensus::Network, legacy::keys as transparent, zip32::DiversifierIndex, zcash_primitives::{legacy::keys as transparent, zip32::DiversifierIndex},
},
}; };
#[test] #[test]
fn verify_schema() { fn verify_schema() {
let data_file = NamedTempFile::new().unwrap(); let st = TestBuilder::new().build();
let mut db_data = WalletDb::for_path(data_file.path(), testing::network()).unwrap();
init_wallet_db(&mut db_data, None).unwrap();
use regex::Regex; use regex::Regex;
let re = Regex::new(r"\s+").unwrap(); let re = Regex::new(r"\s+").unwrap();
@ -569,7 +561,8 @@ mod tests {
)", )",
]; ];
let mut tables_query = db_data let mut tables_query = st
.wallet()
.conn .conn
.prepare("SELECT sql FROM sqlite_schema WHERE type = 'table' ORDER BY tbl_name") .prepare("SELECT sql FROM sqlite_schema WHERE type = 'table' ORDER BY tbl_name")
.unwrap(); .unwrap();
@ -609,7 +602,7 @@ mod tests {
AND (scan_queue.block_range_end - 1) >= shard.subtree_end_height AND (scan_queue.block_range_end - 1) >= shard.subtree_end_height
) )
WHERE scan_queue.priority > {}", WHERE scan_queue.priority > {}",
u32::from(testing::network().activation_height(NetworkUpgrade::Sapling).unwrap()), u32::from(st.network().activation_height(NetworkUpgrade::Sapling).unwrap()),
priority_code(&ScanPriority::Scanned), priority_code(&ScanPriority::Scanned),
), ),
// v_transactions // v_transactions
@ -750,7 +743,8 @@ mod tests {
OR sapling_received_notes.is_change = 0".to_owned(), OR sapling_received_notes.is_change = 0".to_owned(),
]; ];
let mut views_query = db_data let mut views_query = st
.wallet()
.conn .conn
.prepare("SELECT sql FROM sqlite_schema WHERE type = 'view' ORDER BY tbl_name") .prepare("SELECT sql FROM sqlite_schema WHERE type = 'view' ORDER BY tbl_name")
.unwrap(); .unwrap();
@ -768,7 +762,7 @@ mod tests {
#[test] #[test]
fn init_migrate_from_0_3_0() { fn init_migrate_from_0_3_0() {
fn init_0_3_0<P>( fn init_0_3_0<P: consensus::Parameters>(
wdb: &mut WalletDb<rusqlite::Connection, P>, wdb: &mut WalletDb<rusqlite::Connection, P>,
extfvk: &ExtendedFullViewingKey, extfvk: &ExtendedFullViewingKey,
account: AccountId, account: AccountId,
@ -852,11 +846,11 @@ mod tests {
)?; )?;
let address = encode_payment_address( let address = encode_payment_address(
testing::network().hrp_sapling_payment_address(), wdb.params.hrp_sapling_payment_address(),
&extfvk.default_address().1, &extfvk.default_address().1,
); );
let extfvk = encode_extended_full_viewing_key( let extfvk = encode_extended_full_viewing_key(
testing::network().hrp_sapling_extended_full_viewing_key(), wdb.params.hrp_sapling_extended_full_viewing_key(),
extfvk, extfvk,
); );
wdb.conn.execute( wdb.conn.execute(
@ -872,19 +866,21 @@ mod tests {
Ok(()) Ok(())
} }
let data_file = NamedTempFile::new().unwrap();
let mut db_data = WalletDb::for_path(data_file.path(), Network::TestNetwork).unwrap();
let seed = [0xab; 32]; let seed = [0xab; 32];
let account = AccountId::from(0); let account = AccountId::from(0);
let secret_key = sapling::spending_key(&seed, testing::network().coin_type(), account); let secret_key = sapling::spending_key(&seed, db_data.params.coin_type(), account);
let extfvk = secret_key.to_extended_full_viewing_key(); let extfvk = secret_key.to_extended_full_viewing_key();
let data_file = NamedTempFile::new().unwrap();
let mut db_data = WalletDb::for_path(data_file.path(), testing::network()).unwrap();
init_0_3_0(&mut db_data, &extfvk, account).unwrap(); init_0_3_0(&mut db_data, &extfvk, account).unwrap();
init_wallet_db(&mut db_data, Some(Secret::new(seed.to_vec()))).unwrap(); init_wallet_db(&mut db_data, Some(Secret::new(seed.to_vec()))).unwrap();
} }
#[test] #[test]
fn init_migrate_from_autoshielding_poc() { fn init_migrate_from_autoshielding_poc() {
fn init_autoshielding<P>( fn init_autoshielding<P: consensus::Parameters>(
wdb: &mut WalletDb<rusqlite::Connection, P>, wdb: &mut WalletDb<rusqlite::Connection, P>,
extfvk: &ExtendedFullViewingKey, extfvk: &ExtendedFullViewingKey,
account: AccountId, account: AccountId,
@ -984,11 +980,11 @@ mod tests {
)?; )?;
let address = encode_payment_address( let address = encode_payment_address(
testing::network().hrp_sapling_payment_address(), wdb.params.hrp_sapling_payment_address(),
&extfvk.default_address().1, &extfvk.default_address().1,
); );
let extfvk = encode_extended_full_viewing_key( let extfvk = encode_extended_full_viewing_key(
testing::network().hrp_sapling_extended_full_viewing_key(), wdb.params.hrp_sapling_extended_full_viewing_key(),
extfvk, extfvk,
); );
wdb.conn.execute( wdb.conn.execute(
@ -1038,19 +1034,21 @@ mod tests {
Ok(()) Ok(())
} }
let data_file = NamedTempFile::new().unwrap();
let mut db_data = WalletDb::for_path(data_file.path(), Network::TestNetwork).unwrap();
let seed = [0xab; 32]; let seed = [0xab; 32];
let account = AccountId::from(0); let account = AccountId::from(0);
let secret_key = sapling::spending_key(&seed, testing::network().coin_type(), account); let secret_key = sapling::spending_key(&seed, db_data.params.coin_type(), account);
let extfvk = secret_key.to_extended_full_viewing_key(); let extfvk = secret_key.to_extended_full_viewing_key();
let data_file = NamedTempFile::new().unwrap();
let mut db_data = WalletDb::for_path(data_file.path(), testing::network()).unwrap();
init_autoshielding(&mut db_data, &extfvk, account).unwrap(); init_autoshielding(&mut db_data, &extfvk, account).unwrap();
init_wallet_db(&mut db_data, Some(Secret::new(seed.to_vec()))).unwrap(); init_wallet_db(&mut db_data, Some(Secret::new(seed.to_vec()))).unwrap();
} }
#[test] #[test]
fn init_migrate_from_main_pre_migrations() { fn init_migrate_from_main_pre_migrations() {
fn init_main<P>( fn init_main<P: consensus::Parameters>(
wdb: &mut WalletDb<rusqlite::Connection, P>, wdb: &mut WalletDb<rusqlite::Connection, P>,
ufvk: &UnifiedFullViewingKey, ufvk: &UnifiedFullViewingKey,
account: AccountId, account: AccountId,
@ -1150,9 +1148,9 @@ mod tests {
[], [],
)?; )?;
let ufvk_str = ufvk.encode(&testing::network()); let ufvk_str = ufvk.encode(&wdb.params);
let address_str = let address_str =
RecipientAddress::Unified(ufvk.default_address().0).encode(&testing::network()); RecipientAddress::Unified(ufvk.default_address().0).encode(&wdb.params);
wdb.conn.execute( wdb.conn.execute(
"INSERT INTO accounts (account, ufvk, address, transparent_address) "INSERT INTO accounts (account, ufvk, address, transparent_address)
VALUES (?, ?, ?, '')", VALUES (?, ?, ?, '')",
@ -1168,7 +1166,7 @@ mod tests {
{ {
let taddr = let taddr =
RecipientAddress::Transparent(*ufvk.default_address().0.transparent().unwrap()) RecipientAddress::Transparent(*ufvk.default_address().0.transparent().unwrap())
.encode(&testing::network()); .encode(&wdb.params);
wdb.conn.execute( wdb.conn.execute(
"INSERT INTO blocks (height, hash, time, sapling_tree) VALUES (0, 0, 0, x'000000')", "INSERT INTO blocks (height, hash, time, sapling_tree) VALUES (0, 0, 0, x'000000')",
[], [],
@ -1186,12 +1184,13 @@ mod tests {
Ok(()) Ok(())
} }
let data_file = NamedTempFile::new().unwrap();
let mut db_data = WalletDb::for_path(data_file.path(), Network::TestNetwork).unwrap();
let seed = [0xab; 32]; let seed = [0xab; 32];
let account = AccountId::from(0); let account = AccountId::from(0);
let secret_key = let secret_key = UnifiedSpendingKey::from_seed(&db_data.params, &seed, account).unwrap();
UnifiedSpendingKey::from_seed(&testing::network(), &seed, account).unwrap();
let data_file = NamedTempFile::new().unwrap();
let mut db_data = WalletDb::for_path(data_file.path(), testing::network()).unwrap();
init_main( init_main(
&mut db_data, &mut db_data,
&secret_key.to_unified_full_viewing_key(), &secret_key.to_unified_full_viewing_key(),
@ -1204,7 +1203,7 @@ mod tests {
#[test] #[test]
fn init_accounts_table_only_works_once() { fn init_accounts_table_only_works_once() {
let data_file = NamedTempFile::new().unwrap(); let data_file = NamedTempFile::new().unwrap();
let mut db_data = WalletDb::for_path(data_file.path(), testing::network()).unwrap(); let mut db_data = WalletDb::for_path(data_file.path(), Network::TestNetwork).unwrap();
init_wallet_db(&mut db_data, Some(Secret::new(vec![]))).unwrap(); init_wallet_db(&mut db_data, Some(Secret::new(vec![]))).unwrap();
// We can call the function as many times as we want with no data // We can call the function as many times as we want with no data
@ -1215,13 +1214,13 @@ mod tests {
let account = AccountId::from(0); let account = AccountId::from(0);
// First call with data should initialise the accounts table // First call with data should initialise the accounts table
let extsk = sapling::spending_key(&seed, network().coin_type(), account); let extsk = sapling::spending_key(&seed, db_data.params.coin_type(), account);
let dfvk = extsk.to_diversifiable_full_viewing_key(); let dfvk = extsk.to_diversifiable_full_viewing_key();
#[cfg(feature = "transparent-inputs")] #[cfg(feature = "transparent-inputs")]
let ufvk = UnifiedFullViewingKey::new( let ufvk = UnifiedFullViewingKey::new(
Some( Some(
transparent::AccountPrivKey::from_seed(&network(), &seed, account) transparent::AccountPrivKey::from_seed(&db_data.params, &seed, account)
.unwrap() .unwrap()
.to_account_pubkey(), .to_account_pubkey(),
), ),
@ -1243,8 +1242,9 @@ mod tests {
#[test] #[test]
fn init_accounts_table_allows_no_gaps() { fn init_accounts_table_allows_no_gaps() {
let params = Network::TestNetwork;
let data_file = NamedTempFile::new().unwrap(); let data_file = NamedTempFile::new().unwrap();
let mut db_data = WalletDb::for_path(data_file.path(), network()).unwrap(); let mut db_data = WalletDb::for_path(data_file.path(), params).unwrap();
init_wallet_db(&mut db_data, Some(Secret::new(vec![]))).unwrap(); init_wallet_db(&mut db_data, Some(Secret::new(vec![]))).unwrap();
// allow sequential initialization // allow sequential initialization
@ -1253,7 +1253,7 @@ mod tests {
ids.iter() ids.iter()
.map(|a| { .map(|a| {
let account = AccountId::from(*a); let account = AccountId::from(*a);
UnifiedSpendingKey::from_seed(&network(), &seed, account) UnifiedSpendingKey::from_seed(&params, &seed, account)
.map(|k| (account, k.to_unified_full_viewing_key())) .map(|k| (account, k.to_unified_full_viewing_key()))
.unwrap() .unwrap()
}) })
@ -1273,7 +1273,7 @@ mod tests {
#[test] #[test]
fn init_blocks_table_only_works_once() { fn init_blocks_table_only_works_once() {
let data_file = NamedTempFile::new().unwrap(); let data_file = NamedTempFile::new().unwrap();
let mut db_data = WalletDb::for_path(data_file.path(), testing::network()).unwrap(); let mut db_data = WalletDb::for_path(data_file.path(), Network::TestNetwork).unwrap();
init_wallet_db(&mut db_data, Some(Secret::new(vec![]))).unwrap(); init_wallet_db(&mut db_data, Some(Secret::new(vec![]))).unwrap();
// First call with data should initialise the blocks table // First call with data should initialise the blocks table
@ -1300,14 +1300,14 @@ mod tests {
#[test] #[test]
fn init_accounts_table_stores_correct_address() { fn init_accounts_table_stores_correct_address() {
let data_file = NamedTempFile::new().unwrap(); let data_file = NamedTempFile::new().unwrap();
let mut db_data = WalletDb::for_path(data_file.path(), testing::network()).unwrap(); let mut db_data = WalletDb::for_path(data_file.path(), Network::TestNetwork).unwrap();
init_wallet_db(&mut db_data, None).unwrap(); init_wallet_db(&mut db_data, None).unwrap();
let seed = [0u8; 32]; let seed = [0u8; 32];
// Add an account to the wallet // Add an account to the wallet
let account_id = AccountId::from(0); let account_id = AccountId::from(0);
let usk = UnifiedSpendingKey::from_seed(&testing::network(), &seed, account_id).unwrap(); let usk = UnifiedSpendingKey::from_seed(&db_data.params, &seed, account_id).unwrap();
let ufvk = usk.to_unified_full_viewing_key(); let ufvk = usk.to_unified_full_viewing_key();
let expected_address = ufvk.sapling().unwrap().default_address().1; let expected_address = ufvk.sapling().unwrap().default_address().1;
let ufvks = HashMap::from([(account_id, ufvk)]); let ufvks = HashMap::from([(account_id, ufvk)]);

View File

@ -283,10 +283,9 @@ mod tests {
use tempfile::NamedTempFile; use tempfile::NamedTempFile;
use zcash_client_backend::keys::UnifiedSpendingKey; use zcash_client_backend::keys::UnifiedSpendingKey;
use zcash_primitives::zip32::AccountId; use zcash_primitives::{consensus::Network, zip32::AccountId};
use crate::{ use crate::{
testing,
wallet::init::{init_wallet_db_internal, migrations::addresses_table}, wallet::init::{init_wallet_db_internal, migrations::addresses_table},
WalletDb, WalletDb,
}; };
@ -310,19 +309,19 @@ mod tests {
#[test] #[test]
fn transaction_views() { fn transaction_views() {
let network = Network::TestNetwork;
let data_file = NamedTempFile::new().unwrap(); let data_file = NamedTempFile::new().unwrap();
let mut db_data = WalletDb::for_path(data_file.path(), testing::network()).unwrap(); let mut db_data = WalletDb::for_path(data_file.path(), network).unwrap();
init_wallet_db_internal(&mut db_data, None, &[addresses_table::MIGRATION_ID]).unwrap(); init_wallet_db_internal(&mut db_data, None, &[addresses_table::MIGRATION_ID]).unwrap();
let usk = let usk =
UnifiedSpendingKey::from_seed(&testing::network(), &[0u8; 32][..], AccountId::from(0)) UnifiedSpendingKey::from_seed(&network, &[0u8; 32][..], AccountId::from(0)).unwrap();
.unwrap();
let ufvk = usk.to_unified_full_viewing_key(); let ufvk = usk.to_unified_full_viewing_key();
db_data db_data
.conn .conn
.execute( .execute(
"INSERT INTO accounts (account, ufvk) VALUES (0, ?)", "INSERT INTO accounts (account, ufvk) VALUES (0, ?)",
params![ufvk.encode(&testing::network())], params![ufvk.encode(&network)],
) )
.unwrap(); .unwrap();
@ -402,8 +401,9 @@ mod tests {
#[test] #[test]
#[cfg(feature = "transparent-inputs")] #[cfg(feature = "transparent-inputs")]
fn migrate_from_wm2() { fn migrate_from_wm2() {
let network = Network::TestNetwork;
let data_file = NamedTempFile::new().unwrap(); let data_file = NamedTempFile::new().unwrap();
let mut db_data = WalletDb::for_path(data_file.path(), testing::network()).unwrap(); let mut db_data = WalletDb::for_path(data_file.path(), network).unwrap();
init_wallet_db_internal( init_wallet_db_internal(
&mut db_data, &mut db_data,
None, None,
@ -440,8 +440,7 @@ mod tests {
tx.write(&mut tx_bytes).unwrap(); tx.write(&mut tx_bytes).unwrap();
let usk = let usk =
UnifiedSpendingKey::from_seed(&testing::network(), &[0u8; 32][..], AccountId::from(0)) UnifiedSpendingKey::from_seed(&network, &[0u8; 32][..], AccountId::from(0)).unwrap();
.unwrap();
let ufvk = usk.to_unified_full_viewing_key(); let ufvk = usk.to_unified_full_viewing_key();
let (ua, _) = ufvk.default_address(); let (ua, _) = ufvk.default_address();
let taddr = ufvk let taddr = ufvk
@ -451,11 +450,11 @@ mod tests {
.ok() .ok()
.map(|k| k.derive_address(0).unwrap()) .map(|k| k.derive_address(0).unwrap())
}) })
.map(|a| a.encode(&testing::network())); .map(|a| a.encode(&network));
db_data.conn.execute( db_data.conn.execute(
"INSERT INTO accounts (account, ufvk, address, transparent_address) VALUES (0, ?, ?, ?)", "INSERT INTO accounts (account, ufvk, address, transparent_address) VALUES (0, ?, ?, ?)",
params![ufvk.encode(&testing::network()), ua.encode(&testing::network()), &taddr] params![ufvk.encode(&network), ua.encode(&network), &taddr]
).unwrap(); ).unwrap();
db_data db_data
.conn .conn

View File

@ -233,10 +233,9 @@ mod tests {
use tempfile::NamedTempFile; use tempfile::NamedTempFile;
use zcash_client_backend::keys::UnifiedSpendingKey; use zcash_client_backend::keys::UnifiedSpendingKey;
use zcash_primitives::zip32::AccountId; use zcash_primitives::{consensus::Network, zip32::AccountId};
use crate::{ use crate::{
testing,
wallet::init::{init_wallet_db_internal, migrations::v_transactions_net}, wallet::init::{init_wallet_db_internal, migrations::v_transactions_net},
WalletDb, WalletDb,
}; };
@ -244,19 +243,19 @@ mod tests {
#[test] #[test]
fn received_notes_nullable_migration() { fn received_notes_nullable_migration() {
let data_file = NamedTempFile::new().unwrap(); let data_file = NamedTempFile::new().unwrap();
let mut db_data = WalletDb::for_path(data_file.path(), testing::network()).unwrap(); let mut db_data = WalletDb::for_path(data_file.path(), Network::TestNetwork).unwrap();
init_wallet_db_internal(&mut db_data, None, &[v_transactions_net::MIGRATION_ID]).unwrap(); init_wallet_db_internal(&mut db_data, None, &[v_transactions_net::MIGRATION_ID]).unwrap();
// Create an account in the wallet // Create an account in the wallet
let usk0 = let usk0 =
UnifiedSpendingKey::from_seed(&testing::network(), &[0u8; 32][..], AccountId::from(0)) UnifiedSpendingKey::from_seed(&db_data.params, &[0u8; 32][..], AccountId::from(0))
.unwrap(); .unwrap();
let ufvk0 = usk0.to_unified_full_viewing_key(); let ufvk0 = usk0.to_unified_full_viewing_key();
db_data db_data
.conn .conn
.execute( .execute(
"INSERT INTO accounts (account, ufvk) VALUES (0, ?)", "INSERT INTO accounts (account, ufvk) VALUES (0, ?)",
params![ufvk0.encode(&testing::network())], params![ufvk0.encode(&db_data.params)],
) )
.unwrap(); .unwrap();

View File

@ -212,10 +212,9 @@ mod tests {
use tempfile::NamedTempFile; use tempfile::NamedTempFile;
use zcash_client_backend::keys::UnifiedSpendingKey; use zcash_client_backend::keys::UnifiedSpendingKey;
use zcash_primitives::zip32::AccountId; use zcash_primitives::{consensus::Network, zip32::AccountId};
use crate::{ use crate::{
testing,
wallet::init::{init_wallet_db_internal, migrations::add_transaction_views}, wallet::init::{init_wallet_db_internal, migrations::add_transaction_views},
WalletDb, WalletDb,
}; };
@ -223,32 +222,32 @@ mod tests {
#[test] #[test]
fn v_transactions_net() { fn v_transactions_net() {
let data_file = NamedTempFile::new().unwrap(); let data_file = NamedTempFile::new().unwrap();
let mut db_data = WalletDb::for_path(data_file.path(), testing::network()).unwrap(); let mut db_data = WalletDb::for_path(data_file.path(), Network::TestNetwork).unwrap();
init_wallet_db_internal(&mut db_data, None, &[add_transaction_views::MIGRATION_ID]) init_wallet_db_internal(&mut db_data, None, &[add_transaction_views::MIGRATION_ID])
.unwrap(); .unwrap();
// Create two accounts in the wallet. // Create two accounts in the wallet.
let usk0 = let usk0 =
UnifiedSpendingKey::from_seed(&testing::network(), &[0u8; 32][..], AccountId::from(0)) UnifiedSpendingKey::from_seed(&db_data.params, &[0u8; 32][..], AccountId::from(0))
.unwrap(); .unwrap();
let ufvk0 = usk0.to_unified_full_viewing_key(); let ufvk0 = usk0.to_unified_full_viewing_key();
db_data db_data
.conn .conn
.execute( .execute(
"INSERT INTO accounts (account, ufvk) VALUES (0, ?)", "INSERT INTO accounts (account, ufvk) VALUES (0, ?)",
params![ufvk0.encode(&testing::network())], params![ufvk0.encode(&db_data.params)],
) )
.unwrap(); .unwrap();
let usk1 = let usk1 =
UnifiedSpendingKey::from_seed(&testing::network(), &[1u8; 32][..], AccountId::from(1)) UnifiedSpendingKey::from_seed(&db_data.params, &[1u8; 32][..], AccountId::from(1))
.unwrap(); .unwrap();
let ufvk1 = usk1.to_unified_full_viewing_key(); let ufvk1 = usk1.to_unified_full_viewing_key();
db_data db_data
.conn .conn
.execute( .execute(
"INSERT INTO accounts (account, ufvk) VALUES (1, ?)", "INSERT INTO accounts (account, ufvk) VALUES (1, ?)",
params![ufvk1.encode(&testing::network())], params![ufvk1.encode(&db_data.params)],
) )
.unwrap(); .unwrap();

View File

@ -439,7 +439,7 @@ pub(crate) mod tests {
use crate::{ use crate::{
error::SqliteClientError, error::SqliteClientError,
testing::{self, network, AddressType, BlockCache, TestBuilder, TestState}, testing::{AddressType, BlockCache, TestBuilder, TestState},
wallet::{commitment_tree, get_balance, get_balance_at}, wallet::{commitment_tree, get_balance, get_balance_at},
AccountId, NoteId, ReceivedNoteId, AccountId, NoteId, ReceivedNoteId,
}; };
@ -532,7 +532,7 @@ pub(crate) mod tests {
let ufvks = [(account, usk.to_unified_full_viewing_key())] let ufvks = [(account, usk.to_unified_full_viewing_key())]
.into_iter() .into_iter()
.collect(); .collect();
let decrypted_outputs = decrypt_transaction(&testing::network(), h + 1, &tx, &ufvks); let decrypted_outputs = decrypt_transaction(&st.network(), h + 1, &tx, &ufvks);
assert_eq!(decrypted_outputs.len(), 2); assert_eq!(decrypted_outputs.len(), 2);
let mut found_tx_change_memo = false; let mut found_tx_change_memo = false;
@ -609,7 +609,7 @@ pub(crate) mod tests {
#[test] #[test]
fn create_to_address_fails_on_incorrect_usk() { fn create_to_address_fails_on_incorrect_usk() {
let mut st = TestBuilder::new().with_seed(Secret::new(vec![])).build(); let mut st = TestBuilder::new().build();
// Add an account to the wallet // Add an account to the wallet
let seed = Secret::new([0u8; 32].to_vec()); let seed = Secret::new([0u8; 32].to_vec());
@ -619,7 +619,7 @@ pub(crate) mod tests {
// Create a USK that doesn't exist in the wallet // Create a USK that doesn't exist in the wallet
let acct1 = AccountId::from(1); let acct1 = AccountId::from(1);
let usk1 = UnifiedSpendingKey::from_seed(&network(), &[1u8; 32], acct1).unwrap(); let usk1 = UnifiedSpendingKey::from_seed(&st.network(), &[1u8; 32], acct1).unwrap();
// Attempting to spend with a USK that is not in the wallet results in an error // Attempting to spend with a USK that is not in the wallet results in an error
assert_matches!( assert_matches!(
@ -778,10 +778,7 @@ pub(crate) mod tests {
#[test] #[test]
fn create_to_address_fails_on_locked_notes() { fn create_to_address_fails_on_locked_notes() {
let mut st = TestBuilder::new() let mut st = TestBuilder::new().with_block_cache().build();
.with_block_cache()
.with_seed(Secret::new(vec![]))
.build();
// Add an account to the wallet // Add an account to the wallet
let seed = Secret::new([0u8; 32].to_vec()); let seed = Secret::new([0u8; 32].to_vec());
@ -900,7 +897,7 @@ pub(crate) mod tests {
let to = addr2.into(); let to = addr2.into();
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
let send_and_recover_with_policy = |test: &mut TestState<BlockCache>, let send_and_recover_with_policy = |st: &mut TestState<BlockCache>,
ovk_policy| ovk_policy|
-> Result< -> Result<
Option<(Note, PaymentAddress, MemoBytes)>, Option<(Note, PaymentAddress, MemoBytes)>,
@ -912,7 +909,7 @@ pub(crate) mod tests {
ReceivedNoteId, ReceivedNoteId,
>, >,
> { > {
let txid = test.create_spend_to_address( let txid = st.create_spend_to_address(
&usk, &usk,
&to, &to,
Amount::from_u64(15000).unwrap(), Amount::from_u64(15000).unwrap(),
@ -922,7 +919,7 @@ pub(crate) mod tests {
)?; )?;
// Fetch the transaction from the database // Fetch the transaction from the database
let raw_tx: Vec<_> = test let raw_tx: Vec<_> = st
.wallet() .wallet()
.conn .conn
.query_row( .query_row(
@ -937,7 +934,7 @@ pub(crate) mod tests {
for output in tx.sapling_bundle().unwrap().shielded_outputs() { for output in tx.sapling_bundle().unwrap().shielded_outputs() {
// Find the output that decrypts with the external OVK // Find the output that decrypts with the external OVK
let result = try_sapling_output_recovery( let result = try_sapling_output_recovery(
&network(), &st.network(),
h1, h1,
&dfvk.to_ovk(Scope::External), &dfvk.to_ovk(Scope::External),
output, output,

View File

@ -739,6 +739,7 @@ mod tests {
use incrementalmerkletree::{Hashable, Level}; use incrementalmerkletree::{Hashable, Level};
use secrecy::Secret; use secrecy::Secret;
use zcash_client_backend::data_api::{ use zcash_client_backend::data_api::{
chain::CommitmentTreeRoot, chain::CommitmentTreeRoot,
scanning::{ScanPriority, ScanRange}, scanning::{ScanPriority, ScanRange},
@ -752,7 +753,7 @@ mod tests {
}; };
use crate::{ use crate::{
testing::{sapling_activation_height, AddressType, TestBuilder}, testing::{birthday_at_sapling_activation, AddressType, TestBuilder},
wallet::{init::init_blocks_table, scanning::suggest_scan_ranges}, wallet::{init::init_blocks_table, scanning::suggest_scan_ranges},
}; };
@ -1085,11 +1086,11 @@ mod tests {
let mut st = TestBuilder::new() let mut st = TestBuilder::new()
.with_block_cache() .with_block_cache()
.with_seed(Secret::new(vec![])) .with_test_account(birthday_at_sapling_activation)
.with_test_account()
.build(); .build();
let dfvk = st.test_account_sapling().unwrap(); let dfvk = st.test_account_sapling().unwrap();
let sapling_activation_height = st.sapling_activation_height();
assert_matches!( assert_matches!(
// In the following, we don't care what the root hashes are, they just need to be // In the following, we don't care what the root hashes are, they just need to be
@ -1098,15 +1099,15 @@ mod tests {
0, 0,
&[ &[
CommitmentTreeRoot::from_parts( CommitmentTreeRoot::from_parts(
sapling_activation_height() + 100, sapling_activation_height + 100,
Node::empty_root(Level::from(0)) Node::empty_root(Level::from(0))
), ),
CommitmentTreeRoot::from_parts( CommitmentTreeRoot::from_parts(
sapling_activation_height() + 200, sapling_activation_height + 200,
Node::empty_root(Level::from(1)) Node::empty_root(Level::from(1))
), ),
CommitmentTreeRoot::from_parts( CommitmentTreeRoot::from_parts(
sapling_activation_height() + 300, sapling_activation_height + 300,
Node::empty_root(Level::from(2)) Node::empty_root(Level::from(2))
), ),
] ]
@ -1118,7 +1119,7 @@ mod tests {
// of 10 blocks. After `scan_cached_blocks`, the scan queue should have a requested scan // of 10 blocks. After `scan_cached_blocks`, the scan queue should have a requested scan
// range of 300..310 with `FoundNote` priority, 310..320 with `Scanned` priority. // range of 300..310 with `FoundNote` priority, 310..320 with `Scanned` priority.
let initial_sapling_tree_size = (0x1 << 16) * 3 + 5; let initial_sapling_tree_size = (0x1 << 16) * 3 + 5;
let initial_height = sapling_activation_height() + 310; let initial_height = sapling_activation_height + 310;
let value = Amount::from_u64(50000).unwrap(); let value = Amount::from_u64(50000).unwrap();
st.generate_block_at( st.generate_block_at(
@ -1141,7 +1142,7 @@ mod tests {
st.scan_cached_blocks(initial_height, 10); st.scan_cached_blocks(initial_height, 10);
// Verify the that adjacent range needed to make the note spendable has been prioritized. // Verify the that adjacent range needed to make the note spendable has been prioritized.
let sap_active = u32::from(sapling_activation_height()); let sap_active = u32::from(sapling_activation_height);
assert_matches!( assert_matches!(
st.wallet().suggest_scan_ranges(), st.wallet().suggest_scan_ranges(),
Ok(scan_ranges) if scan_ranges == vec![ Ok(scan_ranges) if scan_ranges == vec![
@ -1162,7 +1163,7 @@ mod tests {
// future. // future.
assert_matches!( assert_matches!(
st.wallet_mut() st.wallet_mut()
.update_chain_tip(sapling_activation_height() + 340), .update_chain_tip(sapling_activation_height + 340),
Ok(()) Ok(())
); );
@ -1179,7 +1180,7 @@ mod tests {
// Now simulate a jump ahead more than 100 blocks. // Now simulate a jump ahead more than 100 blocks.
assert_matches!( assert_matches!(
st.wallet_mut() st.wallet_mut()
.update_chain_tip(sapling_activation_height() + 450), .update_chain_tip(sapling_activation_height + 450),
Ok(()) Ok(())
); );
@ -1196,23 +1197,21 @@ mod tests {
} }
#[test] #[test]
fn init_blocks_table_creates_ignored_range() { fn create_account_creates_ignored_range() {
use ScanPriority::*; use ScanPriority::*;
let mut st = TestBuilder::new().with_seed(Secret::new(vec![])).build(); let mut st = TestBuilder::new().build();
let sap_active = st let sap_active = st.sapling_activation_height();
.wallet()
.params // We use Canopy activation as an arbitrary birthday height that's greater than Sapling
.activation_height(NetworkUpgrade::Sapling) // activation.
.unwrap();
// Initialise the blocks table. We use Canopy activation as an arbitrary birthday height
// that's greater than Sapling activation.
let birthday_height = st let birthday_height = st
.wallet() .network()
.params
.activation_height(NetworkUpgrade::Canopy) .activation_height(NetworkUpgrade::Canopy)
.unwrap(); .unwrap();
// call `init_blocks_table` to initialize the scan queue
init_blocks_table( init_blocks_table(
st.wallet_mut(), st.wallet_mut(),
birthday_height, birthday_height,
@ -1222,6 +1221,10 @@ mod tests {
) )
.unwrap(); .unwrap();
let seed = Secret::new(vec![0u8; 32]);
let (_, usk) = st.wallet_mut().create_account(&seed).unwrap();
let _dfvk = usk.to_unified_full_viewing_key().sapling().unwrap().clone();
let expected = vec![ let expected = vec![
// The range up to and including the wallet's birthday height is ignored. // The range up to and including the wallet's birthday height is ignored.
scan_range( scan_range(
@ -1289,9 +1292,7 @@ mod tests {
), ),
]; ];
assert_matches!( let actual = suggest_scan_ranges(&st.wallet().conn, Ignored).unwrap();
suggest_scan_ranges(&st.wallet().conn, Ignored), assert_eq!(actual, expected);
Ok(scan_ranges) if scan_ranges == expected
);
} }
} }