zcash_client_sqlite: Modify `TestState` to allow initialization with chain state.
This commit is contained in:
parent
978f838aae
commit
dc4fccf566
|
@ -71,6 +71,8 @@ and this library adheres to Rust's notion of
|
||||||
- `get_transaction` now returns `Result<Option<Transaction>, _>` rather
|
- `get_transaction` now returns `Result<Option<Transaction>, _>` rather
|
||||||
than returning an `Err` if the `txid` parameter does not correspond to
|
than returning an `Err` if the `txid` parameter does not correspond to
|
||||||
a transaction in the database.
|
a transaction in the database.
|
||||||
|
- `WalletWrite::create_account` now takes its `AccountBirthday` argument by
|
||||||
|
reference.
|
||||||
- Changes to the `InputSource` trait:
|
- Changes to the `InputSource` trait:
|
||||||
- `select_spendable_notes` now takes its `target_value` argument as a
|
- `select_spendable_notes` now takes its `target_value` argument as a
|
||||||
`NonNegativeAmount`. Also, it now returns a `SpendableNotes` data
|
`NonNegativeAmount`. Also, it now returns a `SpendableNotes` data
|
||||||
|
|
|
@ -1297,11 +1297,7 @@ impl<AccountId> SentTransactionOutput<AccountId> {
|
||||||
/// note commitment tree state is recorded at that height.
|
/// note commitment tree state is recorded at that height.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct AccountBirthday {
|
pub struct AccountBirthday {
|
||||||
height: BlockHeight,
|
prior_chain_state: ChainState,
|
||||||
sapling_frontier: Frontier<sapling::Node, { sapling::NOTE_COMMITMENT_TREE_DEPTH }>,
|
|
||||||
#[cfg(feature = "orchard")]
|
|
||||||
orchard_frontier:
|
|
||||||
Frontier<orchard::tree::MerkleHashOrchard, { orchard::NOTE_COMMITMENT_TREE_DEPTH as u8 }>,
|
|
||||||
recover_until: Option<BlockHeight>,
|
recover_until: Option<BlockHeight>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1326,10 +1322,9 @@ impl From<io::Error> for BirthdayError {
|
||||||
impl AccountBirthday {
|
impl AccountBirthday {
|
||||||
/// Constructs a new [`AccountBirthday`] from its constituent parts.
|
/// Constructs a new [`AccountBirthday`] from its constituent parts.
|
||||||
///
|
///
|
||||||
/// * `height`: The birthday height of the account. This is defined as the height of the first
|
/// * `prior_chain_state`: The chain state prior to the birthday height of the account. The
|
||||||
/// block to be scanned in wallet recovery.
|
/// birthday height is defined as the height of the first block to be scanned in wallet
|
||||||
/// * `sapling_frontier`: The Sapling note commitment tree frontier as of the end of the block
|
/// recovery.
|
||||||
/// prior to the birthday height.
|
|
||||||
/// * `recover_until`: An optional height at which the wallet should exit "recovery mode". In
|
/// * `recover_until`: An optional height at which the wallet should exit "recovery mode". In
|
||||||
/// order to avoid confusing shifts in wallet balance and spendability that may temporarily be
|
/// order to avoid confusing shifts in wallet balance and spendability that may temporarily be
|
||||||
/// visible to a user during the process of recovering from seed, wallets may optionally set a
|
/// visible to a user during the process of recovering from seed, wallets may optionally set a
|
||||||
|
@ -1340,20 +1335,9 @@ impl AccountBirthday {
|
||||||
/// This API is intended primarily to be used in testing contexts; under normal circumstances,
|
/// This API is intended primarily to be used in testing contexts; under normal circumstances,
|
||||||
/// [`AccountBirthday::from_treestate`] should be used instead.
|
/// [`AccountBirthday::from_treestate`] should be used instead.
|
||||||
#[cfg(feature = "test-dependencies")]
|
#[cfg(feature = "test-dependencies")]
|
||||||
pub fn from_parts(
|
pub fn from_parts(prior_chain_state: ChainState, recover_until: Option<BlockHeight>) -> Self {
|
||||||
height: BlockHeight,
|
|
||||||
sapling_frontier: Frontier<sapling::Node, { sapling::NOTE_COMMITMENT_TREE_DEPTH }>,
|
|
||||||
#[cfg(feature = "orchard")] orchard_frontier: Frontier<
|
|
||||||
orchard::tree::MerkleHashOrchard,
|
|
||||||
{ orchard::NOTE_COMMITMENT_TREE_DEPTH as u8 },
|
|
||||||
>,
|
|
||||||
recover_until: Option<BlockHeight>,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
height,
|
prior_chain_state,
|
||||||
sapling_frontier,
|
|
||||||
#[cfg(feature = "orchard")]
|
|
||||||
orchard_frontier,
|
|
||||||
recover_until,
|
recover_until,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1373,10 +1357,7 @@ impl AccountBirthday {
|
||||||
recover_until: Option<BlockHeight>,
|
recover_until: Option<BlockHeight>,
|
||||||
) -> Result<Self, BirthdayError> {
|
) -> Result<Self, BirthdayError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
height: BlockHeight::try_from(treestate.height + 1)?,
|
prior_chain_state: treestate.to_chain_state()?,
|
||||||
sapling_frontier: treestate.sapling_tree()?.to_frontier(),
|
|
||||||
#[cfg(feature = "orchard")]
|
|
||||||
orchard_frontier: treestate.orchard_tree()?.to_frontier(),
|
|
||||||
recover_until,
|
recover_until,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1386,7 +1367,7 @@ impl AccountBirthday {
|
||||||
pub fn sapling_frontier(
|
pub fn sapling_frontier(
|
||||||
&self,
|
&self,
|
||||||
) -> &Frontier<sapling::Node, { sapling::NOTE_COMMITMENT_TREE_DEPTH }> {
|
) -> &Frontier<sapling::Node, { sapling::NOTE_COMMITMENT_TREE_DEPTH }> {
|
||||||
&self.sapling_frontier
|
self.prior_chain_state.final_sapling_tree()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the Orchard note commitment tree frontier as of the end of the block at
|
/// Returns the Orchard note commitment tree frontier as of the end of the block at
|
||||||
|
@ -1396,12 +1377,12 @@ impl AccountBirthday {
|
||||||
&self,
|
&self,
|
||||||
) -> &Frontier<orchard::tree::MerkleHashOrchard, { orchard::NOTE_COMMITMENT_TREE_DEPTH as u8 }>
|
) -> &Frontier<orchard::tree::MerkleHashOrchard, { orchard::NOTE_COMMITMENT_TREE_DEPTH as u8 }>
|
||||||
{
|
{
|
||||||
&self.orchard_frontier
|
self.prior_chain_state.final_orchard_tree()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the birthday height of the account.
|
/// Returns the birthday height of the account.
|
||||||
pub fn height(&self) -> BlockHeight {
|
pub fn height(&self) -> BlockHeight {
|
||||||
self.height
|
self.prior_chain_state.block_height() + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the height at which the wallet should exit "recovery mode".
|
/// Returns the height at which the wallet should exit "recovery mode".
|
||||||
|
@ -1409,7 +1390,7 @@ impl AccountBirthday {
|
||||||
self.recover_until
|
self.recover_until
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "test-dependencies")]
|
#[cfg(any(test, feature = "test-dependencies"))]
|
||||||
/// Constructs a new [`AccountBirthday`] at the given network upgrade's activation,
|
/// Constructs a new [`AccountBirthday`] at the given network upgrade's activation,
|
||||||
/// with no "recover until" height.
|
/// with no "recover until" height.
|
||||||
///
|
///
|
||||||
|
@ -1419,17 +1400,18 @@ impl AccountBirthday {
|
||||||
pub fn from_activation<P: zcash_primitives::consensus::Parameters>(
|
pub fn from_activation<P: zcash_primitives::consensus::Parameters>(
|
||||||
params: &P,
|
params: &P,
|
||||||
network_upgrade: NetworkUpgrade,
|
network_upgrade: NetworkUpgrade,
|
||||||
|
prior_block_hash: BlockHash,
|
||||||
) -> AccountBirthday {
|
) -> AccountBirthday {
|
||||||
AccountBirthday::from_parts(
|
AccountBirthday::from_parts(
|
||||||
params.activation_height(network_upgrade).unwrap(),
|
ChainState::empty(
|
||||||
Frontier::empty(),
|
params.activation_height(network_upgrade).unwrap() - 1,
|
||||||
#[cfg(feature = "orchard")]
|
prior_block_hash,
|
||||||
Frontier::empty(),
|
),
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "test-dependencies")]
|
#[cfg(any(test, feature = "test-dependencies"))]
|
||||||
/// Constructs a new [`AccountBirthday`] at Sapling activation, with no
|
/// Constructs a new [`AccountBirthday`] at Sapling activation, with no
|
||||||
/// "recover until" height.
|
/// "recover until" height.
|
||||||
///
|
///
|
||||||
|
@ -1438,8 +1420,9 @@ impl AccountBirthday {
|
||||||
/// Panics if the Sapling activation height is not set.
|
/// Panics if the Sapling activation height is not set.
|
||||||
pub fn from_sapling_activation<P: zcash_primitives::consensus::Parameters>(
|
pub fn from_sapling_activation<P: zcash_primitives::consensus::Parameters>(
|
||||||
params: &P,
|
params: &P,
|
||||||
|
prior_block_hash: BlockHash,
|
||||||
) -> AccountBirthday {
|
) -> AccountBirthday {
|
||||||
Self::from_activation(params, NetworkUpgrade::Sapling)
|
Self::from_activation(params, NetworkUpgrade::Sapling, prior_block_hash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1482,7 +1465,7 @@ pub trait WalletWrite: WalletRead {
|
||||||
fn create_account(
|
fn create_account(
|
||||||
&mut self,
|
&mut self,
|
||||||
seed: &SecretVec<u8>,
|
seed: &SecretVec<u8>,
|
||||||
birthday: AccountBirthday,
|
birthday: &AccountBirthday,
|
||||||
) -> Result<(Self::AccountId, UnifiedSpendingKey), Self::Error>;
|
) -> Result<(Self::AccountId, UnifiedSpendingKey), Self::Error>;
|
||||||
|
|
||||||
/// Generates and persists the next available diversified address, given the current
|
/// Generates and persists the next available diversified address, given the current
|
||||||
|
@ -1887,7 +1870,7 @@ pub mod testing {
|
||||||
fn create_account(
|
fn create_account(
|
||||||
&mut self,
|
&mut self,
|
||||||
seed: &SecretVec<u8>,
|
seed: &SecretVec<u8>,
|
||||||
_birthday: AccountBirthday,
|
_birthday: &AccountBirthday,
|
||||||
) -> Result<(Self::AccountId, UnifiedSpendingKey), Self::Error> {
|
) -> Result<(Self::AccountId, UnifiedSpendingKey), Self::Error> {
|
||||||
let account = zip32::AccountId::ZERO;
|
let account = zip32::AccountId::ZERO;
|
||||||
UnifiedSpendingKey::from_seed(&self.network, seed.expose_secret(), account)
|
UnifiedSpendingKey::from_seed(&self.network, seed.expose_secret(), account)
|
||||||
|
|
|
@ -530,7 +530,7 @@ impl<P: consensus::Parameters> WalletWrite for WalletDb<rusqlite::Connection, P>
|
||||||
fn create_account(
|
fn create_account(
|
||||||
&mut self,
|
&mut self,
|
||||||
seed: &SecretVec<u8>,
|
seed: &SecretVec<u8>,
|
||||||
birthday: AccountBirthday,
|
birthday: &AccountBirthday,
|
||||||
) -> Result<(AccountId, UnifiedSpendingKey), Self::Error> {
|
) -> Result<(AccountId, UnifiedSpendingKey), Self::Error> {
|
||||||
self.transactionally(|wdb| {
|
self.transactionally(|wdb| {
|
||||||
let seed_fingerprint =
|
let seed_fingerprint =
|
||||||
|
@ -1690,7 +1690,8 @@ extern crate assert_matches;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use secrecy::SecretVec;
|
use secrecy::SecretVec;
|
||||||
use zcash_client_backend::data_api::{AccountBirthday, WalletRead, WalletWrite};
|
use zcash_client_backend::data_api::{WalletRead, WalletWrite};
|
||||||
|
use zcash_primitives::block::BlockHash;
|
||||||
|
|
||||||
use crate::{testing::TestBuilder, AccountId, DEFAULT_UA_REQUEST};
|
use crate::{testing::TestBuilder, AccountId, DEFAULT_UA_REQUEST};
|
||||||
|
|
||||||
|
@ -1703,7 +1704,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn validate_seed() {
|
fn validate_seed() {
|
||||||
let st = TestBuilder::new()
|
let st = TestBuilder::new()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
let account = st.test_account().unwrap();
|
let account = st.test_account().unwrap();
|
||||||
|
|
||||||
|
@ -1732,7 +1733,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
pub(crate) fn get_next_available_address() {
|
pub(crate) fn get_next_available_address() {
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
let account = st.test_account().cloned().unwrap();
|
let account = st.test_account().cloned().unwrap();
|
||||||
|
|
||||||
|
@ -1763,7 +1764,7 @@ mod tests {
|
||||||
// Add an account to the wallet.
|
// Add an account to the wallet.
|
||||||
let st = TestBuilder::new()
|
let st = TestBuilder::new()
|
||||||
.with_block_cache()
|
.with_block_cache()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
let account = st.test_account().unwrap();
|
let account = st.test_account().unwrap();
|
||||||
let ufvk = account.usk().to_unified_full_viewing_key();
|
let ufvk = account.usk().to_unified_full_viewing_key();
|
||||||
|
|
|
@ -13,7 +13,7 @@ use rand_chacha::ChaChaRng;
|
||||||
use rand_core::{CryptoRng, RngCore, SeedableRng};
|
use rand_core::{CryptoRng, RngCore, SeedableRng};
|
||||||
use rusqlite::{params, Connection};
|
use rusqlite::{params, Connection};
|
||||||
use secrecy::{Secret, SecretVec};
|
use secrecy::{Secret, SecretVec};
|
||||||
use shardtree::error::ShardTreeError;
|
|
||||||
use tempfile::NamedTempFile;
|
use tempfile::NamedTempFile;
|
||||||
|
|
||||||
#[cfg(feature = "unstable")]
|
#[cfg(feature = "unstable")]
|
||||||
|
@ -102,45 +102,57 @@ use crate::{
|
||||||
|
|
||||||
pub(crate) mod pool;
|
pub(crate) mod pool;
|
||||||
|
|
||||||
|
pub(crate) struct InitialChainState {
|
||||||
|
pub(crate) chain_state: ChainState,
|
||||||
|
pub(crate) prior_sapling_roots: Vec<CommitmentTreeRoot<sapling::Node>>,
|
||||||
|
#[cfg(feature = "orchard")]
|
||||||
|
pub(crate) prior_orchard_roots: Vec<CommitmentTreeRoot<MerkleHashOrchard>>,
|
||||||
|
}
|
||||||
|
|
||||||
/// 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> {
|
||||||
|
rng: ChaChaRng,
|
||||||
network: LocalNetwork,
|
network: LocalNetwork,
|
||||||
cache: Cache,
|
cache: Cache,
|
||||||
test_account_birthday: Option<AccountBirthday>,
|
initial_chain_state: Option<InitialChainState>,
|
||||||
rng: ChaChaRng,
|
account_birthday: Option<AccountBirthday>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestBuilder<()> {
|
impl TestBuilder<()> {
|
||||||
|
pub const DEFAULT_NETWORK: LocalNetwork = LocalNetwork {
|
||||||
|
overwinter: Some(BlockHeight::from_u32(1)),
|
||||||
|
sapling: Some(BlockHeight::from_u32(100_000)),
|
||||||
|
blossom: Some(BlockHeight::from_u32(100_000)),
|
||||||
|
heartwood: Some(BlockHeight::from_u32(100_000)),
|
||||||
|
canopy: Some(BlockHeight::from_u32(100_000)),
|
||||||
|
nu5: Some(BlockHeight::from_u32(100_000)),
|
||||||
|
#[cfg(zcash_unstable = "nu6")]
|
||||||
|
nu6: None,
|
||||||
|
#[cfg(zcash_unstable = "zfuture")]
|
||||||
|
z_future: None,
|
||||||
|
};
|
||||||
|
|
||||||
/// Constructs a new test.
|
/// Constructs a new test.
|
||||||
pub(crate) fn new() -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
TestBuilder {
|
TestBuilder {
|
||||||
|
rng: ChaChaRng::seed_from_u64(0),
|
||||||
// Use a fake network where Sapling through NU5 activate at the same height.
|
// Use a fake network where Sapling through NU5 activate at the same height.
|
||||||
// We pick 100,000 to be large enough to handle any hard-coded test offsets.
|
// We pick 100,000 to be large enough to handle any hard-coded test offsets.
|
||||||
network: LocalNetwork {
|
network: Self::DEFAULT_NETWORK,
|
||||||
overwinter: Some(BlockHeight::from_u32(1)),
|
|
||||||
sapling: Some(BlockHeight::from_u32(100_000)),
|
|
||||||
blossom: Some(BlockHeight::from_u32(100_000)),
|
|
||||||
heartwood: Some(BlockHeight::from_u32(100_000)),
|
|
||||||
canopy: Some(BlockHeight::from_u32(100_000)),
|
|
||||||
nu5: Some(BlockHeight::from_u32(100_000)),
|
|
||||||
#[cfg(zcash_unstable = "nu6")]
|
|
||||||
nu6: None,
|
|
||||||
#[cfg(zcash_unstable = "zfuture")]
|
|
||||||
z_future: None,
|
|
||||||
},
|
|
||||||
cache: (),
|
cache: (),
|
||||||
test_account_birthday: None,
|
initial_chain_state: None,
|
||||||
rng: ChaChaRng::seed_from_u64(0),
|
account_birthday: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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 {
|
||||||
|
rng: self.rng,
|
||||||
network: self.network,
|
network: self.network,
|
||||||
cache: BlockCache::new(),
|
cache: BlockCache::new(),
|
||||||
test_account_birthday: self.test_account_birthday,
|
initial_chain_state: self.initial_chain_state,
|
||||||
rng: self.rng,
|
account_birthday: self.account_birthday,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,20 +160,69 @@ 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 {
|
||||||
|
rng: self.rng,
|
||||||
network: self.network,
|
network: self.network,
|
||||||
cache: FsBlockCache::new(),
|
cache: FsBlockCache::new(),
|
||||||
test_account_birthday: self.test_account_birthday,
|
initial_chain_state: self.initial_chain_state,
|
||||||
rng: self.rng,
|
account_birthday: self.account_birthday,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Cache> TestBuilder<Cache> {
|
impl<Cache> TestBuilder<Cache> {
|
||||||
pub(crate) fn with_test_account<F: FnOnce(&LocalNetwork) -> AccountBirthday>(
|
pub(crate) fn with_initial_chain_state(
|
||||||
mut self,
|
mut self,
|
||||||
birthday: F,
|
chain_state: impl FnOnce(&mut ChaChaRng, &LocalNetwork) -> InitialChainState,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
self.test_account_birthday = Some(birthday(&self.network));
|
assert!(self.initial_chain_state.is_none());
|
||||||
|
assert!(self.account_birthday.is_none());
|
||||||
|
self.initial_chain_state = Some(chain_state(&mut self.rng, &self.network));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn with_account_birthday(
|
||||||
|
mut self,
|
||||||
|
birthday: impl FnOnce(
|
||||||
|
&mut ChaChaRng,
|
||||||
|
&LocalNetwork,
|
||||||
|
Option<&InitialChainState>,
|
||||||
|
) -> AccountBirthday,
|
||||||
|
) -> Self {
|
||||||
|
assert!(self.account_birthday.is_none());
|
||||||
|
self.account_birthday = Some(birthday(
|
||||||
|
&mut self.rng,
|
||||||
|
&self.network,
|
||||||
|
self.initial_chain_state.as_ref(),
|
||||||
|
));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn with_account_from_sapling_activation(mut self, prev_hash: BlockHash) -> Self {
|
||||||
|
assert!(self.account_birthday.is_none());
|
||||||
|
self.account_birthday = Some(AccountBirthday::from_parts(
|
||||||
|
ChainState::empty(
|
||||||
|
self.network
|
||||||
|
.activation_height(NetworkUpgrade::Sapling)
|
||||||
|
.unwrap()
|
||||||
|
- 1,
|
||||||
|
prev_hash,
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn with_account_having_current_birthday(mut self) -> Self {
|
||||||
|
assert!(self.account_birthday.is_none());
|
||||||
|
assert!(self.initial_chain_state.is_some());
|
||||||
|
self.account_birthday = Some(AccountBirthday::from_parts(
|
||||||
|
self.initial_chain_state
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.chain_state
|
||||||
|
.clone(),
|
||||||
|
None,
|
||||||
|
));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,24 +232,75 @@ impl<Cache> TestBuilder<Cache> {
|
||||||
let mut db_data = WalletDb::for_path(data_file.path(), self.network).unwrap();
|
let mut db_data = WalletDb::for_path(data_file.path(), self.network).unwrap();
|
||||||
init_wallet_db(&mut db_data, None).unwrap();
|
init_wallet_db(&mut db_data, None).unwrap();
|
||||||
|
|
||||||
let test_account = if let Some(birthday) = self.test_account_birthday {
|
let mut cached_blocks = BTreeMap::new();
|
||||||
|
|
||||||
|
if let Some(initial_state) = self.initial_chain_state {
|
||||||
|
db_data
|
||||||
|
.put_sapling_subtree_roots(0, &initial_state.prior_sapling_roots)
|
||||||
|
.unwrap();
|
||||||
|
db_data
|
||||||
|
.with_sapling_tree_mut(|t| {
|
||||||
|
t.insert_frontier(
|
||||||
|
initial_state.chain_state.final_sapling_tree().clone(),
|
||||||
|
Retention::Checkpoint {
|
||||||
|
id: initial_state.chain_state.block_height(),
|
||||||
|
is_marked: false,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
#[cfg(feature = "orchard")]
|
||||||
|
{
|
||||||
|
db_data
|
||||||
|
.put_orchard_subtree_roots(0, &initial_state.prior_orchard_roots)
|
||||||
|
.unwrap();
|
||||||
|
db_data
|
||||||
|
.with_orchard_tree_mut(|t| {
|
||||||
|
t.insert_frontier(
|
||||||
|
initial_state.chain_state.final_orchard_tree().clone(),
|
||||||
|
Retention::Checkpoint {
|
||||||
|
id: initial_state.chain_state.block_height(),
|
||||||
|
is_marked: false,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let final_sapling_tree_size =
|
||||||
|
initial_state.chain_state.final_sapling_tree().tree_size() as u32;
|
||||||
|
let _final_orchard_tree_size = 0;
|
||||||
|
#[cfg(feature = "orchard")]
|
||||||
|
let _final_orchard_tree_size =
|
||||||
|
initial_state.chain_state.final_orchard_tree().tree_size() as u32;
|
||||||
|
|
||||||
|
cached_blocks.insert(
|
||||||
|
initial_state.chain_state.block_height(),
|
||||||
|
CachedBlock {
|
||||||
|
chain_state: initial_state.chain_state.clone(),
|
||||||
|
sapling_end_size: final_sapling_tree_size,
|
||||||
|
orchard_end_size: _final_orchard_tree_size,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
let test_account = self.account_birthday.map(|birthday| {
|
||||||
let seed = Secret::new(vec![0u8; 32]);
|
let seed = Secret::new(vec![0u8; 32]);
|
||||||
let (account_id, usk) = db_data.create_account(&seed, birthday.clone()).unwrap();
|
let (account_id, usk) = db_data.create_account(&seed, &birthday).unwrap();
|
||||||
Some((
|
(
|
||||||
seed,
|
seed,
|
||||||
TestAccount {
|
TestAccount {
|
||||||
account_id,
|
account_id,
|
||||||
usk,
|
usk,
|
||||||
birthday,
|
birthday,
|
||||||
},
|
},
|
||||||
))
|
)
|
||||||
} else {
|
});
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
TestState {
|
TestState {
|
||||||
cache: self.cache,
|
cache: self.cache,
|
||||||
cached_blocks: BTreeMap::new(),
|
cached_blocks,
|
||||||
latest_block_height: None,
|
latest_block_height: None,
|
||||||
_data_file: data_file,
|
_data_file: data_file,
|
||||||
db_data,
|
db_data,
|
||||||
|
@ -341,67 +453,6 @@ where
|
||||||
self.cache.insert(&compact_block)
|
self.cache.insert(&compact_block)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ensure that the provided chain state and subtree roots exist in the wallet's note
|
|
||||||
/// commitment tree(s). This may result in a conflict if either the provided subtree roots or
|
|
||||||
/// the chain state conflict with existing note commitment tree data.
|
|
||||||
pub(crate) fn establish_chain_state(
|
|
||||||
&mut self,
|
|
||||||
state: ChainState,
|
|
||||||
prior_sapling_roots: &[CommitmentTreeRoot<sapling::Node>],
|
|
||||||
#[cfg(feature = "orchard")] prior_orchard_roots: &[CommitmentTreeRoot<MerkleHashOrchard>],
|
|
||||||
) -> Result<(), ShardTreeError<commitment_tree::Error>> {
|
|
||||||
self.wallet_mut()
|
|
||||||
.put_sapling_subtree_roots(0, prior_sapling_roots)?;
|
|
||||||
#[cfg(feature = "orchard")]
|
|
||||||
self.wallet_mut()
|
|
||||||
.put_orchard_subtree_roots(0, prior_orchard_roots)?;
|
|
||||||
|
|
||||||
self.wallet_mut().with_sapling_tree_mut(|t| {
|
|
||||||
t.insert_frontier(
|
|
||||||
state.final_sapling_tree().clone(),
|
|
||||||
Retention::Checkpoint {
|
|
||||||
id: state.block_height(),
|
|
||||||
is_marked: false,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
let final_sapling_tree_size = state.final_sapling_tree().tree_size() as u32;
|
|
||||||
|
|
||||||
#[cfg(feature = "orchard")]
|
|
||||||
self.wallet_mut().with_orchard_tree_mut(|t| {
|
|
||||||
t.insert_frontier(
|
|
||||||
state.final_orchard_tree().clone(),
|
|
||||||
Retention::Checkpoint {
|
|
||||||
id: state.block_height(),
|
|
||||||
is_marked: false,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let _final_orchard_tree_size = 0;
|
|
||||||
#[cfg(feature = "orchard")]
|
|
||||||
let _final_orchard_tree_size = state.final_orchard_tree().tree_size() as u32;
|
|
||||||
|
|
||||||
self.insert_cached_block(state, final_sapling_tree_size, _final_orchard_tree_size);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn insert_cached_block(
|
|
||||||
&mut self,
|
|
||||||
chain_state: ChainState,
|
|
||||||
sapling_end_size: u32,
|
|
||||||
orchard_end_size: u32,
|
|
||||||
) {
|
|
||||||
self.cached_blocks.insert(
|
|
||||||
chain_state.block_height(),
|
|
||||||
CachedBlock {
|
|
||||||
chain_state,
|
|
||||||
sapling_end_size,
|
|
||||||
orchard_end_size,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a fake block at the expected next height containing a single output of the
|
/// Creates a fake block at the expected next height containing a single output of the
|
||||||
/// given value, and inserts it into the cache.
|
/// given value, and inserts it into the cache.
|
||||||
pub(crate) fn generate_next_block<Fvk: TestFvk>(
|
pub(crate) fn generate_next_block<Fvk: TestFvk>(
|
||||||
|
@ -692,11 +743,6 @@ impl<Cache> TestState<Cache> {
|
||||||
self.db_data.params
|
self.db_data.params
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Exposes the random number source for the test state
|
|
||||||
pub(crate) fn rng(&mut self) -> &mut ChaChaRng {
|
|
||||||
&mut self.rng
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convenience method for obtaining the Sapling activation height for the network under test.
|
/// Convenience method for obtaining the Sapling activation height for the network under test.
|
||||||
pub(crate) fn sapling_activation_height(&self) -> BlockHeight {
|
pub(crate) fn sapling_activation_height(&self) -> BlockHeight {
|
||||||
self.db_data
|
self.db_data
|
||||||
|
|
|
@ -53,9 +53,6 @@ use crate::{
|
||||||
AccountId, NoteId, ReceivedNoteId,
|
AccountId, NoteId, ReceivedNoteId,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "orchard")]
|
|
||||||
use zcash_primitives::consensus::NetworkUpgrade;
|
|
||||||
|
|
||||||
#[cfg(feature = "transparent-inputs")]
|
#[cfg(feature = "transparent-inputs")]
|
||||||
use {
|
use {
|
||||||
zcash_client_backend::{
|
zcash_client_backend::{
|
||||||
|
@ -129,7 +126,7 @@ pub(crate) trait ShieldedPoolTester {
|
||||||
pub(crate) fn send_single_step_proposed_transfer<T: ShieldedPoolTester>() {
|
pub(crate) fn send_single_step_proposed_transfer<T: ShieldedPoolTester>() {
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_block_cache()
|
.with_block_cache()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let account = st.test_account().cloned().unwrap();
|
let account = st.test_account().cloned().unwrap();
|
||||||
|
@ -287,7 +284,7 @@ pub(crate) fn send_multi_step_proposed_transfer<T: ShieldedPoolTester>() {
|
||||||
|
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_block_cache()
|
.with_block_cache()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let account = st.test_account().cloned().unwrap();
|
let account = st.test_account().cloned().unwrap();
|
||||||
|
@ -439,7 +436,7 @@ pub(crate) fn send_multi_step_proposed_transfer<T: ShieldedPoolTester>() {
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
pub(crate) fn create_to_address_fails_on_incorrect_usk<T: ShieldedPoolTester>() {
|
pub(crate) fn create_to_address_fails_on_incorrect_usk<T: ShieldedPoolTester>() {
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
let dfvk = T::test_account_fvk(&st);
|
let dfvk = T::test_account_fvk(&st);
|
||||||
let to = T::fvk_default_address(&dfvk);
|
let to = T::fvk_default_address(&dfvk);
|
||||||
|
@ -467,7 +464,7 @@ pub(crate) fn create_to_address_fails_on_incorrect_usk<T: ShieldedPoolTester>()
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
pub(crate) fn proposal_fails_with_no_blocks<T: ShieldedPoolTester>() {
|
pub(crate) fn proposal_fails_with_no_blocks<T: ShieldedPoolTester>() {
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let account_id = st.test_account().unwrap().account_id();
|
let account_id = st.test_account().unwrap().account_id();
|
||||||
|
@ -496,7 +493,7 @@ pub(crate) fn proposal_fails_with_no_blocks<T: ShieldedPoolTester>() {
|
||||||
pub(crate) fn spend_fails_on_unverified_notes<T: ShieldedPoolTester>() {
|
pub(crate) fn spend_fails_on_unverified_notes<T: ShieldedPoolTester>() {
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_block_cache()
|
.with_block_cache()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let account = st.test_account().cloned().unwrap();
|
let account = st.test_account().cloned().unwrap();
|
||||||
|
@ -647,7 +644,7 @@ pub(crate) fn spend_fails_on_unverified_notes<T: ShieldedPoolTester>() {
|
||||||
pub(crate) fn spend_fails_on_locked_notes<T: ShieldedPoolTester>() {
|
pub(crate) fn spend_fails_on_locked_notes<T: ShieldedPoolTester>() {
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_block_cache()
|
.with_block_cache()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let account = st.test_account().cloned().unwrap();
|
let account = st.test_account().cloned().unwrap();
|
||||||
|
@ -785,7 +782,7 @@ pub(crate) fn spend_fails_on_locked_notes<T: ShieldedPoolTester>() {
|
||||||
pub(crate) fn ovk_policy_prevents_recovery_from_chain<T: ShieldedPoolTester>() {
|
pub(crate) fn ovk_policy_prevents_recovery_from_chain<T: ShieldedPoolTester>() {
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_block_cache()
|
.with_block_cache()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let account = st.test_account().cloned().unwrap();
|
let account = st.test_account().cloned().unwrap();
|
||||||
|
@ -881,7 +878,7 @@ pub(crate) fn ovk_policy_prevents_recovery_from_chain<T: ShieldedPoolTester>() {
|
||||||
pub(crate) fn spend_succeeds_to_t_addr_zero_change<T: ShieldedPoolTester>() {
|
pub(crate) fn spend_succeeds_to_t_addr_zero_change<T: ShieldedPoolTester>() {
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_block_cache()
|
.with_block_cache()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let account = st.test_account().cloned().unwrap();
|
let account = st.test_account().cloned().unwrap();
|
||||||
|
@ -928,7 +925,7 @@ pub(crate) fn spend_succeeds_to_t_addr_zero_change<T: ShieldedPoolTester>() {
|
||||||
pub(crate) fn change_note_spends_succeed<T: ShieldedPoolTester>() {
|
pub(crate) fn change_note_spends_succeed<T: ShieldedPoolTester>() {
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_block_cache()
|
.with_block_cache()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let account = st.test_account().cloned().unwrap();
|
let account = st.test_account().cloned().unwrap();
|
||||||
|
@ -998,17 +995,11 @@ pub(crate) fn external_address_change_spends_detected_in_restore_from_seed<
|
||||||
|
|
||||||
// Add two accounts to the wallet.
|
// Add two accounts to the wallet.
|
||||||
let seed = Secret::new([0u8; 32].to_vec());
|
let seed = Secret::new([0u8; 32].to_vec());
|
||||||
let birthday = AccountBirthday::from_sapling_activation(&st.network());
|
let birthday = AccountBirthday::from_sapling_activation(&st.network(), BlockHash([0; 32]));
|
||||||
let (account_id, usk) = st
|
let (account_id, usk) = st.wallet_mut().create_account(&seed, &birthday).unwrap();
|
||||||
.wallet_mut()
|
|
||||||
.create_account(&seed, birthday.clone())
|
|
||||||
.unwrap();
|
|
||||||
let dfvk = T::sk_to_fvk(T::usk_to_sk(&usk));
|
let dfvk = T::sk_to_fvk(T::usk_to_sk(&usk));
|
||||||
|
|
||||||
let (account2, usk2) = st
|
let (account2, usk2) = st.wallet_mut().create_account(&seed, &birthday).unwrap();
|
||||||
.wallet_mut()
|
|
||||||
.create_account(&seed, birthday.clone())
|
|
||||||
.unwrap();
|
|
||||||
let dfvk2 = T::sk_to_fvk(T::usk_to_sk(&usk2));
|
let dfvk2 = T::sk_to_fvk(T::usk_to_sk(&usk2));
|
||||||
|
|
||||||
// Add funds to the wallet in a single note
|
// Add funds to the wallet in a single note
|
||||||
|
@ -1081,16 +1072,13 @@ pub(crate) fn external_address_change_spends_detected_in_restore_from_seed<
|
||||||
st.reset();
|
st.reset();
|
||||||
|
|
||||||
// Account creation and DFVK derivation should be deterministic.
|
// Account creation and DFVK derivation should be deterministic.
|
||||||
let (_, restored_usk) = st
|
let (_, restored_usk) = st.wallet_mut().create_account(&seed, &birthday).unwrap();
|
||||||
.wallet_mut()
|
|
||||||
.create_account(&seed, birthday.clone())
|
|
||||||
.unwrap();
|
|
||||||
assert!(T::fvks_equal(
|
assert!(T::fvks_equal(
|
||||||
&T::sk_to_fvk(T::usk_to_sk(&restored_usk)),
|
&T::sk_to_fvk(T::usk_to_sk(&restored_usk)),
|
||||||
&dfvk,
|
&dfvk,
|
||||||
));
|
));
|
||||||
|
|
||||||
let (_, restored_usk2) = st.wallet_mut().create_account(&seed, birthday).unwrap();
|
let (_, restored_usk2) = st.wallet_mut().create_account(&seed, &birthday).unwrap();
|
||||||
assert!(T::fvks_equal(
|
assert!(T::fvks_equal(
|
||||||
&T::sk_to_fvk(T::usk_to_sk(&restored_usk2)),
|
&T::sk_to_fvk(T::usk_to_sk(&restored_usk2)),
|
||||||
&dfvk2,
|
&dfvk2,
|
||||||
|
@ -1105,7 +1093,7 @@ pub(crate) fn external_address_change_spends_detected_in_restore_from_seed<
|
||||||
pub(crate) fn zip317_spend<T: ShieldedPoolTester>() {
|
pub(crate) fn zip317_spend<T: ShieldedPoolTester>() {
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_block_cache()
|
.with_block_cache()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let account = st.test_account().cloned().unwrap();
|
let account = st.test_account().cloned().unwrap();
|
||||||
|
@ -1199,7 +1187,7 @@ pub(crate) fn zip317_spend<T: ShieldedPoolTester>() {
|
||||||
pub(crate) fn shield_transparent<T: ShieldedPoolTester>() {
|
pub(crate) fn shield_transparent<T: ShieldedPoolTester>() {
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_block_cache()
|
.with_block_cache()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let account = st.test_account().cloned().unwrap();
|
let account = st.test_account().cloned().unwrap();
|
||||||
|
@ -1259,7 +1247,7 @@ pub(crate) fn shield_transparent<T: ShieldedPoolTester>() {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(crate) fn birthday_in_anchor_shard<T: ShieldedPoolTester>() {
|
pub(crate) fn birthday_in_anchor_shard<T: ShieldedPoolTester>() {
|
||||||
// Use a non-zero birthday offset because Sapling and NU5 are activated at the same height.
|
// Use a non-zero birthday offset because Sapling and NU5 are activated at the same height.
|
||||||
let (mut st, dfvk, birthday, _) = test_with_nu5_birthday_offset::<T>(76);
|
let (mut st, dfvk, birthday, _) = test_with_nu5_birthday_offset::<T>(76, BlockHash([0; 32]));
|
||||||
|
|
||||||
// Set up the following situation:
|
// Set up the following situation:
|
||||||
//
|
//
|
||||||
|
@ -1364,7 +1352,7 @@ pub(crate) fn birthday_in_anchor_shard<T: ShieldedPoolTester>() {
|
||||||
pub(crate) fn checkpoint_gaps<T: ShieldedPoolTester>() {
|
pub(crate) fn checkpoint_gaps<T: ShieldedPoolTester>() {
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_block_cache()
|
.with_block_cache()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let account = st.test_account().cloned().unwrap();
|
let account = st.test_account().cloned().unwrap();
|
||||||
|
@ -1433,7 +1421,8 @@ pub(crate) fn checkpoint_gaps<T: ShieldedPoolTester>() {
|
||||||
pub(crate) fn pool_crossing_required<P0: ShieldedPoolTester, P1: ShieldedPoolTester>() {
|
pub(crate) fn pool_crossing_required<P0: ShieldedPoolTester, P1: ShieldedPoolTester>() {
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_block_cache()
|
.with_block_cache()
|
||||||
.with_test_account(|params| AccountBirthday::from_activation(params, NetworkUpgrade::Nu5))
|
.with_account_from_sapling_activation(BlockHash([0; 32])) // TODO: Allow for Orchard
|
||||||
|
// activation after Sapling
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let account = st.test_account().cloned().unwrap();
|
let account = st.test_account().cloned().unwrap();
|
||||||
|
@ -1522,7 +1511,8 @@ pub(crate) fn pool_crossing_required<P0: ShieldedPoolTester, P1: ShieldedPoolTes
|
||||||
pub(crate) fn fully_funded_fully_private<P0: ShieldedPoolTester, P1: ShieldedPoolTester>() {
|
pub(crate) fn fully_funded_fully_private<P0: ShieldedPoolTester, P1: ShieldedPoolTester>() {
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_block_cache()
|
.with_block_cache()
|
||||||
.with_test_account(|params| AccountBirthday::from_activation(params, NetworkUpgrade::Nu5))
|
.with_account_from_sapling_activation(BlockHash([0; 32])) // TODO: Allow for Orchard
|
||||||
|
// activation after Sapling
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let account = st.test_account().cloned().unwrap();
|
let account = st.test_account().cloned().unwrap();
|
||||||
|
@ -1612,7 +1602,7 @@ pub(crate) fn fully_funded_fully_private<P0: ShieldedPoolTester, P1: ShieldedPoo
|
||||||
pub(crate) fn valid_chain_states<T: ShieldedPoolTester>() {
|
pub(crate) fn valid_chain_states<T: ShieldedPoolTester>() {
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_block_cache()
|
.with_block_cache()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let dfvk = T::test_account_fvk(&st);
|
let dfvk = T::test_account_fvk(&st);
|
||||||
|
@ -1646,7 +1636,7 @@ pub(crate) fn valid_chain_states<T: ShieldedPoolTester>() {
|
||||||
pub(crate) fn invalid_chain_cache_disconnected<T: ShieldedPoolTester>() {
|
pub(crate) fn invalid_chain_cache_disconnected<T: ShieldedPoolTester>() {
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_block_cache()
|
.with_block_cache()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let dfvk = T::test_account_fvk(&st);
|
let dfvk = T::test_account_fvk(&st);
|
||||||
|
@ -1697,7 +1687,7 @@ pub(crate) fn invalid_chain_cache_disconnected<T: ShieldedPoolTester>() {
|
||||||
pub(crate) fn data_db_truncation<T: ShieldedPoolTester>() {
|
pub(crate) fn data_db_truncation<T: ShieldedPoolTester>() {
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_block_cache()
|
.with_block_cache()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let account = st.test_account().cloned().unwrap();
|
let account = st.test_account().cloned().unwrap();
|
||||||
|
@ -1753,7 +1743,7 @@ pub(crate) fn data_db_truncation<T: ShieldedPoolTester>() {
|
||||||
pub(crate) fn scan_cached_blocks_allows_blocks_out_of_order<T: ShieldedPoolTester>() {
|
pub(crate) fn scan_cached_blocks_allows_blocks_out_of_order<T: ShieldedPoolTester>() {
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_block_cache()
|
.with_block_cache()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let account = st.test_account().cloned().unwrap();
|
let account = st.test_account().cloned().unwrap();
|
||||||
|
@ -1813,7 +1803,7 @@ pub(crate) fn scan_cached_blocks_allows_blocks_out_of_order<T: ShieldedPoolTeste
|
||||||
pub(crate) fn scan_cached_blocks_finds_received_notes<T: ShieldedPoolTester>() {
|
pub(crate) fn scan_cached_blocks_finds_received_notes<T: ShieldedPoolTester>() {
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_block_cache()
|
.with_block_cache()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let account = st.test_account().cloned().unwrap();
|
let account = st.test_account().cloned().unwrap();
|
||||||
|
@ -1856,7 +1846,7 @@ pub(crate) fn scan_cached_blocks_finds_received_notes<T: ShieldedPoolTester>() {
|
||||||
pub(crate) fn scan_cached_blocks_finds_change_notes<T: ShieldedPoolTester>() {
|
pub(crate) fn scan_cached_blocks_finds_change_notes<T: ShieldedPoolTester>() {
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_block_cache()
|
.with_block_cache()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let account = st.test_account().cloned().unwrap();
|
let account = st.test_account().cloned().unwrap();
|
||||||
|
@ -1895,7 +1885,7 @@ pub(crate) fn scan_cached_blocks_finds_change_notes<T: ShieldedPoolTester>() {
|
||||||
pub(crate) fn scan_cached_blocks_detects_spends_out_of_order<T: ShieldedPoolTester>() {
|
pub(crate) fn scan_cached_blocks_detects_spends_out_of_order<T: ShieldedPoolTester>() {
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_block_cache()
|
.with_block_cache()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let account = st.test_account().cloned().unwrap();
|
let account = st.test_account().cloned().unwrap();
|
||||||
|
|
|
@ -351,7 +351,7 @@ pub(crate) fn add_account<P: consensus::Parameters>(
|
||||||
params: &P,
|
params: &P,
|
||||||
kind: AccountSource,
|
kind: AccountSource,
|
||||||
viewing_key: ViewingKey,
|
viewing_key: ViewingKey,
|
||||||
birthday: AccountBirthday,
|
birthday: &AccountBirthday,
|
||||||
) -> Result<AccountId, SqliteClientError> {
|
) -> Result<AccountId, SqliteClientError> {
|
||||||
let (hd_seed_fingerprint, hd_account_index) = match kind {
|
let (hd_seed_fingerprint, hd_account_index) = match kind {
|
||||||
AccountSource::Derived {
|
AccountSource::Derived {
|
||||||
|
@ -2720,7 +2720,7 @@ mod tests {
|
||||||
use std::num::NonZeroU32;
|
use std::num::NonZeroU32;
|
||||||
|
|
||||||
use sapling::zip32::ExtendedSpendingKey;
|
use sapling::zip32::ExtendedSpendingKey;
|
||||||
use zcash_client_backend::data_api::{AccountBirthday, AccountSource, WalletRead};
|
use zcash_client_backend::data_api::{AccountSource, WalletRead};
|
||||||
use zcash_primitives::{block::BlockHash, transaction::components::amount::NonNegativeAmount};
|
use zcash_primitives::{block::BlockHash, transaction::components::amount::NonNegativeAmount};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -2749,7 +2749,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_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
let account = st.test_account().unwrap();
|
let account = st.test_account().unwrap();
|
||||||
|
|
||||||
|
@ -2784,7 +2784,7 @@ mod tests {
|
||||||
use crate::testing::TestBuilder;
|
use crate::testing::TestBuilder;
|
||||||
|
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let account_id = st.test_account().unwrap().account_id();
|
let account_id = st.test_account().unwrap().account_id();
|
||||||
|
@ -2873,7 +2873,7 @@ mod tests {
|
||||||
use crate::testing::TestBuilder;
|
use crate::testing::TestBuilder;
|
||||||
|
|
||||||
let st = TestBuilder::new()
|
let st = TestBuilder::new()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
let account_id = st.test_account().unwrap().account_id();
|
let account_id = st.test_account().unwrap().account_id();
|
||||||
let account_parameters = st.wallet().get_account(account_id).unwrap().unwrap();
|
let account_parameters = st.wallet().get_account(account_id).unwrap().unwrap();
|
||||||
|
@ -2892,10 +2892,10 @@ mod tests {
|
||||||
|
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_block_cache()
|
.with_block_cache()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let account = st.test_account().unwrap().clone();
|
let account = st.test_account().cloned().unwrap();
|
||||||
let uaddr = st
|
let uaddr = st
|
||||||
.wallet()
|
.wallet()
|
||||||
.get_current_address(account.account_id())
|
.get_current_address(account.account_id())
|
||||||
|
@ -3043,7 +3043,7 @@ mod tests {
|
||||||
fn block_fully_scanned() {
|
fn block_fully_scanned() {
|
||||||
let mut st = TestBuilder::new()
|
let mut st = TestBuilder::new()
|
||||||
.with_block_cache()
|
.with_block_cache()
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
.with_account_from_sapling_activation(BlockHash([0; 32]))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let block_fully_scanned = |st: &TestState<BlockCache>| {
|
let block_fully_scanned = |st: &TestState<BlockCache>| {
|
||||||
|
|
|
@ -1427,6 +1427,7 @@ mod tests {
|
||||||
#[cfg(feature = "transparent-inputs")]
|
#[cfg(feature = "transparent-inputs")]
|
||||||
fn account_produces_expected_ua_sequence() {
|
fn account_produces_expected_ua_sequence() {
|
||||||
use zcash_client_backend::data_api::{AccountBirthday, AccountSource, WalletRead};
|
use zcash_client_backend::data_api::{AccountBirthday, AccountSource, WalletRead};
|
||||||
|
use zcash_primitives::block::BlockHash;
|
||||||
|
|
||||||
let network = Network::MainNetwork;
|
let network = Network::MainNetwork;
|
||||||
let data_file = NamedTempFile::new().unwrap();
|
let data_file = NamedTempFile::new().unwrap();
|
||||||
|
@ -1445,9 +1446,9 @@ mod tests {
|
||||||
Ok(())
|
Ok(())
|
||||||
);
|
);
|
||||||
|
|
||||||
let birthday = AccountBirthday::from_sapling_activation(&network);
|
let birthday = AccountBirthday::from_sapling_activation(&network, BlockHash([0; 32]));
|
||||||
let (account_id, _usk) = db_data
|
let (account_id, _usk) = db_data
|
||||||
.create_account(&Secret::new(seed.to_vec()), birthday)
|
.create_account(&Secret::new(seed.to_vec()), &birthday)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_matches!(
|
assert_matches!(
|
||||||
db_data.get_account(account_id),
|
db_data.get_account(account_id),
|
||||||
|
|
|
@ -581,9 +581,8 @@ pub(crate) fn update_chain_tip<P: consensus::Parameters>(
|
||||||
pub(crate) mod tests {
|
pub(crate) mod tests {
|
||||||
use std::num::NonZeroU8;
|
use std::num::NonZeroU8;
|
||||||
|
|
||||||
use incrementalmerkletree::{frontier::Frontier, Hashable, Position};
|
use incrementalmerkletree::{frontier::Frontier, Position};
|
||||||
|
|
||||||
use sapling::Node;
|
|
||||||
use secrecy::SecretVec;
|
use secrecy::SecretVec;
|
||||||
use zcash_client_backend::data_api::{
|
use zcash_client_backend::data_api::{
|
||||||
chain::{ChainState, CommitmentTreeRoot},
|
chain::{ChainState, CommitmentTreeRoot},
|
||||||
|
@ -599,7 +598,10 @@ pub(crate) mod tests {
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::SqliteClientError,
|
error::SqliteClientError,
|
||||||
testing::{pool::ShieldedPoolTester, AddressType, BlockCache, TestBuilder, TestState},
|
testing::{
|
||||||
|
pool::ShieldedPoolTester, AddressType, BlockCache, InitialChainState, TestBuilder,
|
||||||
|
TestState,
|
||||||
|
},
|
||||||
wallet::{
|
wallet::{
|
||||||
sapling::tests::SaplingPoolTester,
|
sapling::tests::SaplingPoolTester,
|
||||||
scanning::{insert_queue_entries, replace_queue_entries, suggest_scan_ranges},
|
scanning::{insert_queue_entries, replace_queue_entries, suggest_scan_ranges},
|
||||||
|
@ -609,7 +611,7 @@ pub(crate) mod tests {
|
||||||
|
|
||||||
#[cfg(feature = "orchard")]
|
#[cfg(feature = "orchard")]
|
||||||
use {
|
use {
|
||||||
crate::wallet::orchard::tests::OrchardPoolTester, orchard::tree::MerkleHashOrchard,
|
crate::wallet::orchard::tests::OrchardPoolTester,
|
||||||
zcash_client_backend::data_api::ORCHARD_SHARD_HEIGHT,
|
zcash_client_backend::data_api::ORCHARD_SHARD_HEIGHT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -626,66 +628,75 @@ pub(crate) mod tests {
|
||||||
|
|
||||||
fn scan_complete<T: ShieldedPoolTester>() {
|
fn scan_complete<T: ShieldedPoolTester>() {
|
||||||
use ScanPriority::*;
|
use ScanPriority::*;
|
||||||
let initial_height_offset = 310;
|
|
||||||
let mut st = TestBuilder::new()
|
|
||||||
.with_block_cache()
|
|
||||||
.with_test_account(AccountBirthday::from_sapling_activation)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let sapling_activation_height = st.sapling_activation_height();
|
|
||||||
|
|
||||||
// We'll start inserting leaf notes 5 notes after the end of the third subtree, with a gap
|
// We'll start inserting leaf notes 5 notes after the end of the third subtree, with a gap
|
||||||
// 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.
|
||||||
// We set both Sapling and Orchard to the same initial tree size for simplicity.
|
// We set both Sapling and Orchard to the same initial tree size for simplicity.
|
||||||
|
let prior_block_hash = BlockHash([0; 32]);
|
||||||
let initial_sapling_tree_size: u32 = (0x1 << 16) * 3 + 5;
|
let initial_sapling_tree_size: u32 = (0x1 << 16) * 3 + 5;
|
||||||
let initial_orchard_tree_size: u32 = (0x1 << 16) * 3 + 5;
|
let initial_orchard_tree_size: u32 = (0x1 << 16) * 3 + 5;
|
||||||
|
let initial_height_offset = 310;
|
||||||
|
|
||||||
// Construct a fake chain state for the end of block 300
|
let mut st = TestBuilder::new()
|
||||||
let (prior_sapling_frontiers, sapling_initial_tree) =
|
.with_block_cache()
|
||||||
Frontier::random_with_prior_subtree_roots(
|
.with_initial_chain_state(|rng, network| {
|
||||||
st.rng(),
|
let sapling_activation_height =
|
||||||
initial_sapling_tree_size.into(),
|
network.activation_height(NetworkUpgrade::Sapling).unwrap();
|
||||||
NonZeroU8::new(16).unwrap(),
|
// Construct a fake chain state for the end of block 300
|
||||||
);
|
let (prior_sapling_roots, sapling_initial_tree) =
|
||||||
let sapling_subtree_roots = prior_sapling_frontiers
|
Frontier::random_with_prior_subtree_roots(
|
||||||
.into_iter()
|
rng,
|
||||||
.zip(0u32..)
|
initial_sapling_tree_size.into(),
|
||||||
.map(|(root, i)| {
|
NonZeroU8::new(16).unwrap(),
|
||||||
CommitmentTreeRoot::from_parts(sapling_activation_height + (100 * (i + 1)), root)
|
);
|
||||||
})
|
let prior_sapling_roots = prior_sapling_roots
|
||||||
.collect::<Vec<_>>();
|
.into_iter()
|
||||||
|
.zip(0u32..)
|
||||||
|
.map(|(root, i)| {
|
||||||
|
CommitmentTreeRoot::from_parts(
|
||||||
|
sapling_activation_height + (100 * (i + 1)),
|
||||||
|
root,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
#[cfg(feature = "orchard")]
|
|
||||||
let (prior_orchard_frontiers, orchard_initial_tree) =
|
|
||||||
Frontier::random_with_prior_subtree_roots(
|
|
||||||
st.rng(),
|
|
||||||
initial_orchard_tree_size.into(),
|
|
||||||
NonZeroU8::new(16).unwrap(),
|
|
||||||
);
|
|
||||||
#[cfg(feature = "orchard")]
|
|
||||||
let orchard_subtree_roots = prior_orchard_frontiers
|
|
||||||
.into_iter()
|
|
||||||
.zip(0u32..)
|
|
||||||
.map(|(root, i)| {
|
|
||||||
CommitmentTreeRoot::from_parts(sapling_activation_height + (100 * (i + 1)), root)
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let prior_block_hash = BlockHash([0; 32]);
|
|
||||||
st.establish_chain_state(
|
|
||||||
ChainState::new(
|
|
||||||
sapling_activation_height + initial_height_offset - 1,
|
|
||||||
prior_block_hash,
|
|
||||||
sapling_initial_tree,
|
|
||||||
#[cfg(feature = "orchard")]
|
#[cfg(feature = "orchard")]
|
||||||
orchard_initial_tree,
|
let (prior_orchard_roots, orchard_initial_tree) =
|
||||||
),
|
Frontier::random_with_prior_subtree_roots(
|
||||||
&sapling_subtree_roots,
|
rng,
|
||||||
#[cfg(feature = "orchard")]
|
initial_orchard_tree_size.into(),
|
||||||
&orchard_subtree_roots,
|
NonZeroU8::new(16).unwrap(),
|
||||||
)
|
);
|
||||||
.unwrap();
|
#[cfg(feature = "orchard")]
|
||||||
|
let prior_orchard_roots = prior_orchard_roots
|
||||||
|
.into_iter()
|
||||||
|
.zip(0u32..)
|
||||||
|
.map(|(root, i)| {
|
||||||
|
CommitmentTreeRoot::from_parts(
|
||||||
|
sapling_activation_height + (100 * (i + 1)),
|
||||||
|
root,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
InitialChainState {
|
||||||
|
chain_state: ChainState::new(
|
||||||
|
sapling_activation_height + initial_height_offset - 1,
|
||||||
|
prior_block_hash,
|
||||||
|
sapling_initial_tree,
|
||||||
|
#[cfg(feature = "orchard")]
|
||||||
|
orchard_initial_tree,
|
||||||
|
),
|
||||||
|
prior_sapling_roots,
|
||||||
|
#[cfg(feature = "orchard")]
|
||||||
|
prior_orchard_roots,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.with_account_from_sapling_activation(BlockHash([3; 32]))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let sapling_activation_height = st.sapling_activation_height();
|
||||||
|
|
||||||
let dfvk = T::test_account_fvk(&st);
|
let dfvk = T::test_account_fvk(&st);
|
||||||
let value = NonNegativeAmount::const_from_u64(50000);
|
let value = NonNegativeAmount::const_from_u64(50000);
|
||||||
|
@ -776,37 +787,43 @@ pub(crate) mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn test_with_nu5_birthday_offset<T: ShieldedPoolTester>(
|
pub(crate) fn test_with_nu5_birthday_offset<T: ShieldedPoolTester>(
|
||||||
offset: u32,
|
birthday_offset: u32,
|
||||||
|
prior_block_hash: BlockHash,
|
||||||
) -> (TestState<BlockCache>, T::Fvk, AccountBirthday, u32) {
|
) -> (TestState<BlockCache>, T::Fvk, AccountBirthday, u32) {
|
||||||
let st = TestBuilder::new()
|
let st = TestBuilder::new()
|
||||||
.with_block_cache()
|
.with_block_cache()
|
||||||
.with_test_account(|network| {
|
.with_account_birthday(|rng, network, initial_chain_state| {
|
||||||
|
// We're constructing the birthday without adding any chain data.
|
||||||
|
assert!(initial_chain_state.is_none());
|
||||||
|
|
||||||
// We set the Sapling and Orchard frontiers at the birthday height to be
|
// We set the Sapling and Orchard frontiers at the birthday height to be
|
||||||
// 1234 notes into the second shard.
|
// 1234 notes into the second shard.
|
||||||
let birthday_height =
|
|
||||||
network.activation_height(NetworkUpgrade::Nu5).unwrap() + offset;
|
|
||||||
let frontier_position = Position::from((0x1 << 16) + 1234);
|
let frontier_position = Position::from((0x1 << 16) + 1234);
|
||||||
let sapling_frontier = Frontier::from_parts(
|
let birthday_height =
|
||||||
frontier_position,
|
network.activation_height(NetworkUpgrade::Nu5).unwrap() + birthday_offset;
|
||||||
Node::empty_leaf(),
|
|
||||||
vec![Node::empty_leaf(); frontier_position.past_ommer_count().into()],
|
// Construct a fake chain state for the end of the block with the given
|
||||||
)
|
// birthday_offset from the Nu5 birthday.
|
||||||
.unwrap();
|
let (_, sapling_initial_tree) = Frontier::random_with_prior_subtree_roots(
|
||||||
|
rng,
|
||||||
|
(frontier_position + 1).into(),
|
||||||
|
NonZeroU8::new(16).unwrap(),
|
||||||
|
);
|
||||||
#[cfg(feature = "orchard")]
|
#[cfg(feature = "orchard")]
|
||||||
let orchard_frontier = Frontier::from_parts(
|
let (_, orchard_initial_tree) = Frontier::random_with_prior_subtree_roots(
|
||||||
frontier_position,
|
rng,
|
||||||
MerkleHashOrchard::empty_leaf(),
|
(frontier_position + 1).into(),
|
||||||
vec![
|
NonZeroU8::new(16).unwrap(),
|
||||||
MerkleHashOrchard::empty_leaf();
|
);
|
||||||
frontier_position.past_ommer_count().into()
|
|
||||||
],
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
AccountBirthday::from_parts(
|
AccountBirthday::from_parts(
|
||||||
birthday_height,
|
ChainState::new(
|
||||||
sapling_frontier,
|
birthday_height,
|
||||||
#[cfg(feature = "orchard")]
|
prior_block_hash,
|
||||||
orchard_frontier,
|
sapling_initial_tree,
|
||||||
|
#[cfg(feature = "orchard")]
|
||||||
|
orchard_initial_tree,
|
||||||
|
),
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -834,7 +851,8 @@ pub(crate) mod tests {
|
||||||
use ScanPriority::*;
|
use ScanPriority::*;
|
||||||
|
|
||||||
// Use a non-zero birthday offset because Sapling and NU5 are activated at the same height.
|
// 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::<T>(76);
|
let (st, _, birthday, sap_active) =
|
||||||
|
test_with_nu5_birthday_offset::<T>(76, BlockHash([0; 32]));
|
||||||
let birthday_height = birthday.height().into();
|
let birthday_height = birthday.height().into();
|
||||||
|
|
||||||
let expected = vec![
|
let expected = vec![
|
||||||
|
@ -869,11 +887,8 @@ pub(crate) mod tests {
|
||||||
st.wallet_mut()
|
st.wallet_mut()
|
||||||
.create_account(
|
.create_account(
|
||||||
&SecretVec::new(vec![0; 32]),
|
&SecretVec::new(vec![0; 32]),
|
||||||
AccountBirthday::from_parts(
|
&AccountBirthday::from_parts(
|
||||||
wallet_birthday,
|
ChainState::empty(wallet_birthday - 1, BlockHash([0; 32])),
|
||||||
Frontier::empty(),
|
|
||||||
#[cfg(feature = "orchard")]
|
|
||||||
Frontier::empty(),
|
|
||||||
None,
|
None,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -904,7 +919,8 @@ pub(crate) mod tests {
|
||||||
use ScanPriority::*;
|
use ScanPriority::*;
|
||||||
|
|
||||||
// Use a non-zero birthday offset because Sapling and NU5 are activated at the same height.
|
// 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::<T>(76);
|
let (mut st, _, birthday, sap_active) =
|
||||||
|
test_with_nu5_birthday_offset::<T>(76, BlockHash([0; 32]));
|
||||||
|
|
||||||
// Set up the following situation:
|
// Set up the following situation:
|
||||||
//
|
//
|
||||||
|
@ -921,7 +937,9 @@ pub(crate) mod tests {
|
||||||
|
|
||||||
// Verify that the suggested scan ranges match what is expected.
|
// Verify that the suggested scan ranges match what is expected.
|
||||||
let expected = vec![
|
let expected = vec![
|
||||||
// The wallet's birthday onward is marked for recovery.
|
// The wallet's birthday onward is marked for recovery. Because we don't
|
||||||
|
// yet have any chain state, it is marked with `Historic` priority rather
|
||||||
|
// than `ChainTip`.
|
||||||
scan_range(wallet_birthday..chain_end, Historic),
|
scan_range(wallet_birthday..chain_end, Historic),
|
||||||
// The range below the wallet's birthday height is ignored.
|
// The range below the wallet's birthday height is ignored.
|
||||||
scan_range(sap_active..wallet_birthday, Ignored),
|
scan_range(sap_active..wallet_birthday, Ignored),
|
||||||
|
@ -946,7 +964,8 @@ pub(crate) mod tests {
|
||||||
use ScanPriority::*;
|
use ScanPriority::*;
|
||||||
|
|
||||||
// Use a non-zero birthday offset because Sapling and NU5 are activated at the same height.
|
// 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::<T>(76);
|
let (mut st, _, birthday, sap_active) =
|
||||||
|
test_with_nu5_birthday_offset::<T>(76, BlockHash([0; 32]));
|
||||||
|
|
||||||
// Set up the following situation:
|
// Set up the following situation:
|
||||||
//
|
//
|
||||||
|
@ -1007,7 +1026,8 @@ pub(crate) mod tests {
|
||||||
|
|
||||||
// Use a non-zero birthday offset because Sapling and NU5 are activated at the same height.
|
// Use a non-zero birthday offset because Sapling and NU5 are activated at the same height.
|
||||||
// this birthday is 1234 notes into the second shard
|
// this birthday is 1234 notes into the second shard
|
||||||
let (mut st, dfvk, birthday, sap_active) = test_with_nu5_birthday_offset::<T>(76);
|
let (mut st, dfvk, birthday, sap_active) =
|
||||||
|
test_with_nu5_birthday_offset::<T>(76, BlockHash([0; 32]));
|
||||||
|
|
||||||
// Set up the following situation:
|
// Set up the following situation:
|
||||||
//
|
//
|
||||||
|
@ -1149,7 +1169,8 @@ pub(crate) mod tests {
|
||||||
use ScanPriority::*;
|
use ScanPriority::*;
|
||||||
|
|
||||||
// Use a non-zero birthday offset because Sapling and NU5 are activated at the same height.
|
// Use a non-zero birthday offset because Sapling and NU5 are activated at the same height.
|
||||||
let (mut st, dfvk, birthday, sap_active) = test_with_nu5_birthday_offset::<T>(76);
|
let (mut st, dfvk, birthday, sap_active) =
|
||||||
|
test_with_nu5_birthday_offset::<T>(76, BlockHash([0; 32]));
|
||||||
|
|
||||||
// Set up the following situation:
|
// Set up the following situation:
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in New Issue