zcash_client_backend: Move the `ShieldedPoolTester` trait from `zcash_client_sqlite`
This commit is contained in:
parent
49dffbf6ee
commit
4f5b3efe09
|
@ -0,0 +1,90 @@
|
|||
use std::{cmp::Eq, hash::Hash};
|
||||
|
||||
use incrementalmerkletree::Level;
|
||||
use rand::RngCore;
|
||||
use shardtree::error::ShardTreeError;
|
||||
use zcash_keys::{address::Address, keys::UnifiedSpendingKey};
|
||||
use zcash_primitives::transaction::Transaction;
|
||||
use zcash_protocol::{
|
||||
consensus::{self, BlockHeight},
|
||||
memo::MemoBytes,
|
||||
value::Zatoshis,
|
||||
ShieldedProtocol,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
data_api::{
|
||||
chain::{CommitmentTreeRoot, ScanSummary},
|
||||
DecryptedTransaction, InputSource, WalletCommitmentTrees, WalletRead, WalletSummary,
|
||||
},
|
||||
wallet::{Note, ReceivedNote},
|
||||
};
|
||||
|
||||
use super::{TestFvk, TestState};
|
||||
|
||||
/// Trait that exposes the pool-specific types and operations necessary to run the
|
||||
/// single-shielded-pool tests on a given pool.
|
||||
pub trait ShieldedPoolTester {
|
||||
const SHIELDED_PROTOCOL: ShieldedProtocol;
|
||||
|
||||
type Sk;
|
||||
type Fvk: TestFvk;
|
||||
type MerkleTreeHash;
|
||||
type Note;
|
||||
|
||||
fn test_account_fvk<Cache, DbT: WalletRead, P: consensus::Parameters>(
|
||||
st: &TestState<Cache, DbT, P>,
|
||||
) -> Self::Fvk;
|
||||
fn usk_to_sk(usk: &UnifiedSpendingKey) -> &Self::Sk;
|
||||
fn sk(seed: &[u8]) -> Self::Sk;
|
||||
fn sk_to_fvk(sk: &Self::Sk) -> Self::Fvk;
|
||||
fn sk_default_address(sk: &Self::Sk) -> Address;
|
||||
fn fvk_default_address(fvk: &Self::Fvk) -> Address;
|
||||
fn fvks_equal(a: &Self::Fvk, b: &Self::Fvk) -> bool;
|
||||
|
||||
fn random_fvk(mut rng: impl RngCore) -> Self::Fvk {
|
||||
let sk = {
|
||||
let mut sk_bytes = vec![0; 32];
|
||||
rng.fill_bytes(&mut sk_bytes);
|
||||
Self::sk(&sk_bytes)
|
||||
};
|
||||
|
||||
Self::sk_to_fvk(&sk)
|
||||
}
|
||||
fn random_address(rng: impl RngCore) -> Address {
|
||||
Self::fvk_default_address(&Self::random_fvk(rng))
|
||||
}
|
||||
|
||||
fn empty_tree_leaf() -> Self::MerkleTreeHash;
|
||||
fn empty_tree_root(level: Level) -> Self::MerkleTreeHash;
|
||||
|
||||
fn put_subtree_roots<Cache, DbT: WalletRead + WalletCommitmentTrees, P>(
|
||||
st: &mut TestState<Cache, DbT, P>,
|
||||
start_index: u64,
|
||||
roots: &[CommitmentTreeRoot<Self::MerkleTreeHash>],
|
||||
) -> Result<(), ShardTreeError<<DbT as WalletCommitmentTrees>::Error>>;
|
||||
|
||||
fn next_subtree_index<A: Hash + Eq>(s: &WalletSummary<A>) -> u64;
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn select_spendable_notes<Cache, DbT: InputSource + WalletRead, P>(
|
||||
st: &TestState<Cache, DbT, P>,
|
||||
account: <DbT as InputSource>::AccountId,
|
||||
target_value: Zatoshis,
|
||||
anchor_height: BlockHeight,
|
||||
exclude: &[DbT::NoteRef],
|
||||
) -> Result<Vec<ReceivedNote<DbT::NoteRef, Self::Note>>, <DbT as InputSource>::Error>;
|
||||
|
||||
fn decrypted_pool_outputs_count<A>(d_tx: &DecryptedTransaction<'_, A>) -> usize;
|
||||
|
||||
fn with_decrypted_pool_memos<A>(d_tx: &DecryptedTransaction<'_, A>, f: impl FnMut(&MemoBytes));
|
||||
|
||||
fn try_output_recovery<P: consensus::Parameters>(
|
||||
params: &P,
|
||||
height: BlockHeight,
|
||||
tx: &Transaction,
|
||||
fvk: &Self::Fvk,
|
||||
) -> Option<(Note, Address, MemoBytes)>;
|
||||
|
||||
fn received_note_count(summary: &ScanSummary) -> usize;
|
||||
}
|
|
@ -38,7 +38,7 @@ pub struct DecryptedOutput<Note, AccountId> {
|
|||
transfer_type: TransferType,
|
||||
}
|
||||
|
||||
impl<Note, AccountId: Copy> DecryptedOutput<Note, AccountId> {
|
||||
impl<Note, AccountId> DecryptedOutput<Note, AccountId> {
|
||||
pub fn new(
|
||||
index: usize,
|
||||
note: Note,
|
||||
|
|
|
@ -7,11 +7,11 @@ use std::{
|
|||
num::{NonZeroU32, NonZeroU8},
|
||||
};
|
||||
|
||||
use incrementalmerkletree::{frontier::Frontier, Level};
|
||||
use rand_core::RngCore;
|
||||
use incrementalmerkletree::frontier::Frontier;
|
||||
|
||||
use rusqlite::params;
|
||||
use secrecy::Secret;
|
||||
use shardtree::error::ShardTreeError;
|
||||
|
||||
use zcash_primitives::{
|
||||
block::BlockHash,
|
||||
consensus::{BranchId, NetworkUpgrade, Parameters},
|
||||
|
@ -31,28 +31,25 @@ use zcash_client_backend::{
|
|||
address::Address,
|
||||
data_api::{
|
||||
self,
|
||||
chain::{self, ChainState, CommitmentTreeRoot, ScanSummary},
|
||||
chain::{self, ChainState, CommitmentTreeRoot},
|
||||
error::Error,
|
||||
testing::{
|
||||
input_selector, AddressType, FakeCompactOutput, InitialChainState, TestBuilder,
|
||||
TestFvk, TestState,
|
||||
input_selector, pool::ShieldedPoolTester, AddressType, FakeCompactOutput,
|
||||
InitialChainState, TestBuilder, TestState,
|
||||
},
|
||||
wallet::{
|
||||
decrypt_and_store_transaction,
|
||||
input_selection::{GreedyInputSelector, GreedyInputSelectorError},
|
||||
},
|
||||
Account as _, AccountBirthday, DecryptedTransaction, InputSource, Ratio,
|
||||
WalletCommitmentTrees, WalletRead, WalletSummary, WalletWrite,
|
||||
Account as _, AccountBirthday, Ratio, WalletRead, WalletWrite,
|
||||
},
|
||||
decrypt_transaction,
|
||||
fees::{fixed, standard, DustOutputPolicy},
|
||||
keys::UnifiedSpendingKey,
|
||||
scanning::ScanError,
|
||||
wallet::{Note, OvkPolicy, ReceivedNote},
|
||||
wallet::{Note, OvkPolicy},
|
||||
zip321::{self, Payment, TransactionRequest},
|
||||
ShieldedProtocol,
|
||||
};
|
||||
use zcash_protocol::consensus::{self, BlockHeight};
|
||||
|
||||
use crate::{
|
||||
error::SqliteClientError,
|
||||
|
@ -61,12 +58,13 @@ use crate::{
|
|||
BlockCache,
|
||||
},
|
||||
wallet::{commitment_tree, parse_scope, truncate_to_height},
|
||||
AccountId, NoteId, ReceivedNoteId,
|
||||
NoteId, ReceivedNoteId,
|
||||
};
|
||||
|
||||
#[cfg(feature = "transparent-inputs")]
|
||||
use {
|
||||
zcash_client_backend::wallet::WalletTransparentOutput,
|
||||
crate::AccountId,
|
||||
zcash_client_backend::{data_api::DecryptedTransaction, wallet::WalletTransparentOutput},
|
||||
zcash_primitives::transaction::{
|
||||
components::{OutPoint, TxOut},
|
||||
fees::zip317,
|
||||
|
@ -74,77 +72,13 @@ use {
|
|||
};
|
||||
|
||||
#[cfg(feature = "orchard")]
|
||||
use zcash_client_backend::PoolType;
|
||||
|
||||
/// Trait that exposes the pool-specific types and operations necessary to run the
|
||||
/// single-shielded-pool tests on a given pool.
|
||||
pub(crate) trait ShieldedPoolTester {
|
||||
const SHIELDED_PROTOCOL: ShieldedProtocol;
|
||||
const TABLES_PREFIX: &'static str;
|
||||
|
||||
type Sk;
|
||||
type Fvk: TestFvk;
|
||||
type MerkleTreeHash;
|
||||
type Note;
|
||||
|
||||
fn test_account_fvk<Cache, DbT: WalletRead, P: consensus::Parameters>(
|
||||
st: &TestState<Cache, DbT, P>,
|
||||
) -> Self::Fvk;
|
||||
fn usk_to_sk(usk: &UnifiedSpendingKey) -> &Self::Sk;
|
||||
fn sk(seed: &[u8]) -> Self::Sk;
|
||||
fn sk_to_fvk(sk: &Self::Sk) -> Self::Fvk;
|
||||
fn sk_default_address(sk: &Self::Sk) -> Address;
|
||||
fn fvk_default_address(fvk: &Self::Fvk) -> Address;
|
||||
fn fvks_equal(a: &Self::Fvk, b: &Self::Fvk) -> bool;
|
||||
|
||||
fn random_fvk(mut rng: impl RngCore) -> Self::Fvk {
|
||||
let sk = {
|
||||
let mut sk_bytes = vec![0; 32];
|
||||
rng.fill_bytes(&mut sk_bytes);
|
||||
Self::sk(&sk_bytes)
|
||||
use {
|
||||
zcash_client_backend::PoolType,
|
||||
zcash_protocol::{consensus::BlockHeight, ShieldedProtocol},
|
||||
};
|
||||
|
||||
Self::sk_to_fvk(&sk)
|
||||
}
|
||||
fn random_address(rng: impl RngCore) -> Address {
|
||||
Self::fvk_default_address(&Self::random_fvk(rng))
|
||||
}
|
||||
|
||||
fn empty_tree_leaf() -> Self::MerkleTreeHash;
|
||||
fn empty_tree_root(level: Level) -> Self::MerkleTreeHash;
|
||||
|
||||
fn put_subtree_roots<Cache, DbT: WalletRead + WalletCommitmentTrees, P>(
|
||||
st: &mut TestState<Cache, DbT, P>,
|
||||
start_index: u64,
|
||||
roots: &[CommitmentTreeRoot<Self::MerkleTreeHash>],
|
||||
) -> Result<(), ShardTreeError<<DbT as WalletCommitmentTrees>::Error>>;
|
||||
|
||||
fn next_subtree_index(s: &WalletSummary<AccountId>) -> u64;
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn select_spendable_notes<Cache, DbT: InputSource + WalletRead, P>(
|
||||
st: &TestState<Cache, DbT, P>,
|
||||
account: <DbT as InputSource>::AccountId,
|
||||
target_value: NonNegativeAmount,
|
||||
anchor_height: BlockHeight,
|
||||
exclude: &[DbT::NoteRef],
|
||||
) -> Result<Vec<ReceivedNote<DbT::NoteRef, Self::Note>>, <DbT as InputSource>::Error>;
|
||||
|
||||
fn decrypted_pool_outputs_count(d_tx: &DecryptedTransaction<'_, AccountId>) -> usize;
|
||||
|
||||
fn with_decrypted_pool_memos(
|
||||
d_tx: &DecryptedTransaction<'_, AccountId>,
|
||||
f: impl FnMut(&MemoBytes),
|
||||
);
|
||||
|
||||
fn try_output_recovery<P: consensus::Parameters>(
|
||||
params: &P,
|
||||
height: BlockHeight,
|
||||
tx: &Transaction,
|
||||
fvk: &Self::Fvk,
|
||||
) -> Option<(Note, Address, MemoBytes)>;
|
||||
|
||||
fn received_note_count(summary: &ScanSummary) -> usize;
|
||||
pub(crate) trait ShieldedPoolPersistence {
|
||||
const TABLES_PREFIX: &'static str;
|
||||
}
|
||||
|
||||
pub(crate) fn send_single_step_proposed_transfer<T: ShieldedPoolTester>() {
|
||||
|
@ -1291,7 +1225,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 + ShieldedPoolPersistence>() {
|
||||
let mut st = TestBuilder::new()
|
||||
.with_data_store_factory(TestDbFactory)
|
||||
.with_block_cache(BlockCache::new())
|
||||
|
|
|
@ -1081,17 +1081,19 @@ mod tests {
|
|||
Marking, Position, Retention,
|
||||
};
|
||||
use shardtree::ShardTree;
|
||||
use zcash_client_backend::data_api::chain::CommitmentTreeRoot;
|
||||
use zcash_client_backend::data_api::{
|
||||
chain::CommitmentTreeRoot, testing::pool::ShieldedPoolTester,
|
||||
};
|
||||
use zcash_primitives::consensus::{BlockHeight, Network};
|
||||
|
||||
use super::SqliteShardStore;
|
||||
use crate::{
|
||||
testing::pool::ShieldedPoolTester,
|
||||
testing::pool::ShieldedPoolPersistence,
|
||||
wallet::{init::init_wallet_db, sapling::tests::SaplingPoolTester},
|
||||
WalletDb,
|
||||
};
|
||||
|
||||
fn new_tree<T: ShieldedPoolTester>(
|
||||
fn new_tree<T: ShieldedPoolTester + ShieldedPoolPersistence>(
|
||||
m: usize,
|
||||
) -> ShardTree<SqliteShardStore<rusqlite::Connection, String, 3>, 4, 3> {
|
||||
let data_file = NamedTempFile::new().unwrap();
|
||||
|
@ -1191,7 +1193,7 @@ mod tests {
|
|||
put_shard_roots::<SaplingPoolTester>()
|
||||
}
|
||||
|
||||
fn put_shard_roots<T: ShieldedPoolTester>() {
|
||||
fn put_shard_roots<T: ShieldedPoolTester + ShieldedPoolPersistence>() {
|
||||
let data_file = NamedTempFile::new().unwrap();
|
||||
let mut db_data = WalletDb::for_path(data_file.path(), Network::TestNetwork).unwrap();
|
||||
data_file.keep().unwrap();
|
||||
|
|
|
@ -387,18 +387,21 @@ pub(crate) fn mark_orchard_note_spent(
|
|||
|
||||
#[cfg(test)]
|
||||
pub(crate) mod tests {
|
||||
use std::hash::Hash;
|
||||
|
||||
use incrementalmerkletree::{Hashable, Level};
|
||||
use orchard::{
|
||||
keys::{FullViewingKey, SpendingKey},
|
||||
note_encryption::OrchardDomain,
|
||||
tree::MerkleHashOrchard,
|
||||
};
|
||||
|
||||
use shardtree::error::ShardTreeError;
|
||||
|
||||
use zcash_client_backend::{
|
||||
data_api::{
|
||||
chain::CommitmentTreeRoot, testing::TestState, DecryptedTransaction, InputSource,
|
||||
WalletCommitmentTrees, WalletRead, WalletSummary,
|
||||
chain::CommitmentTreeRoot,
|
||||
testing::{pool::ShieldedPoolTester, TestState},
|
||||
DecryptedTransaction, InputSource, WalletCommitmentTrees, WalletRead, WalletSummary,
|
||||
},
|
||||
wallet::{Note, ReceivedNote},
|
||||
};
|
||||
|
@ -416,15 +419,17 @@ pub(crate) mod tests {
|
|||
};
|
||||
|
||||
use crate::{
|
||||
testing::{self, pool::ShieldedPoolTester},
|
||||
testing::{self, pool::ShieldedPoolPersistence},
|
||||
wallet::sapling::tests::SaplingPoolTester,
|
||||
ORCHARD_TABLES_PREFIX,
|
||||
};
|
||||
|
||||
pub(crate) struct OrchardPoolTester;
|
||||
impl ShieldedPoolPersistence for OrchardPoolTester {
|
||||
const TABLES_PREFIX: &'static str = ORCHARD_TABLES_PREFIX;
|
||||
}
|
||||
impl ShieldedPoolTester for OrchardPoolTester {
|
||||
const SHIELDED_PROTOCOL: ShieldedProtocol = ShieldedProtocol::Orchard;
|
||||
const TABLES_PREFIX: &'static str = ORCHARD_TABLES_PREFIX;
|
||||
// const MERKLE_TREE_DEPTH: u8 = {orchard::NOTE_COMMITMENT_TREE_DEPTH as u8};
|
||||
|
||||
type Sk = SpendingKey;
|
||||
|
@ -491,7 +496,7 @@ pub(crate) mod tests {
|
|||
.put_orchard_subtree_roots(start_index, roots)
|
||||
}
|
||||
|
||||
fn next_subtree_index(s: &WalletSummary<crate::AccountId>) -> u64 {
|
||||
fn next_subtree_index<A: Hash + Eq>(s: &WalletSummary<A>) -> u64 {
|
||||
s.next_orchard_subtree_index()
|
||||
}
|
||||
|
||||
|
@ -514,14 +519,12 @@ pub(crate) mod tests {
|
|||
.map(|n| n.take_orchard())
|
||||
}
|
||||
|
||||
fn decrypted_pool_outputs_count(
|
||||
d_tx: &DecryptedTransaction<'_, crate::AccountId>,
|
||||
) -> usize {
|
||||
fn decrypted_pool_outputs_count<A>(d_tx: &DecryptedTransaction<'_, A>) -> usize {
|
||||
d_tx.orchard_outputs().len()
|
||||
}
|
||||
|
||||
fn with_decrypted_pool_memos(
|
||||
d_tx: &DecryptedTransaction<'_, crate::AccountId>,
|
||||
fn with_decrypted_pool_memos<A>(
|
||||
d_tx: &DecryptedTransaction<'_, A>,
|
||||
mut f: impl FnMut(&MemoBytes),
|
||||
) {
|
||||
for output in d_tx.orchard_outputs() {
|
||||
|
|
|
@ -400,15 +400,27 @@ pub(crate) fn put_received_note<T: ReceivedSaplingOutput>(
|
|||
|
||||
#[cfg(test)]
|
||||
pub(crate) mod tests {
|
||||
use std::hash::Hash;
|
||||
|
||||
use incrementalmerkletree::{Hashable, Level};
|
||||
|
||||
use shardtree::error::ShardTreeError;
|
||||
|
||||
use sapling::{
|
||||
self,
|
||||
note_encryption::try_sapling_output_recovery,
|
||||
zip32::{DiversifiableFullViewingKey, ExtendedSpendingKey},
|
||||
};
|
||||
use shardtree::error::ShardTreeError;
|
||||
|
||||
use zcash_client_backend::{
|
||||
address::Address,
|
||||
data_api::{
|
||||
chain::CommitmentTreeRoot,
|
||||
testing::{pool::ShieldedPoolTester, TestState},
|
||||
DecryptedTransaction, InputSource, WalletCommitmentTrees, WalletRead, WalletSummary,
|
||||
},
|
||||
keys::UnifiedSpendingKey,
|
||||
wallet::{Note, ReceivedNote},
|
||||
ShieldedProtocol,
|
||||
};
|
||||
use zcash_primitives::{
|
||||
consensus::BlockHeight,
|
||||
memo::MemoBytes,
|
||||
|
@ -418,28 +430,19 @@ pub(crate) mod tests {
|
|||
},
|
||||
zip32::Scope,
|
||||
};
|
||||
|
||||
use zcash_client_backend::{
|
||||
address::Address,
|
||||
data_api::{
|
||||
chain::CommitmentTreeRoot, testing::TestState, DecryptedTransaction, InputSource,
|
||||
WalletCommitmentTrees, WalletRead, WalletSummary,
|
||||
},
|
||||
keys::UnifiedSpendingKey,
|
||||
wallet::{Note, ReceivedNote},
|
||||
ShieldedProtocol,
|
||||
};
|
||||
use zcash_protocol::consensus;
|
||||
|
||||
use crate::{
|
||||
testing::{self, pool::ShieldedPoolTester},
|
||||
AccountId, SAPLING_TABLES_PREFIX,
|
||||
testing::{self, pool::ShieldedPoolPersistence},
|
||||
SAPLING_TABLES_PREFIX,
|
||||
};
|
||||
|
||||
pub(crate) struct SaplingPoolTester;
|
||||
impl ShieldedPoolPersistence for SaplingPoolTester {
|
||||
const TABLES_PREFIX: &'static str = SAPLING_TABLES_PREFIX;
|
||||
}
|
||||
impl ShieldedPoolTester for SaplingPoolTester {
|
||||
const SHIELDED_PROTOCOL: ShieldedProtocol = ShieldedProtocol::Sapling;
|
||||
const TABLES_PREFIX: &'static str = SAPLING_TABLES_PREFIX;
|
||||
// const MERKLE_TREE_DEPTH: u8 = sapling::NOTE_COMMITMENT_TREE_DEPTH;
|
||||
|
||||
type Sk = ExtendedSpendingKey;
|
||||
|
@ -494,7 +497,7 @@ pub(crate) mod tests {
|
|||
.put_sapling_subtree_roots(start_index, roots)
|
||||
}
|
||||
|
||||
fn next_subtree_index(s: &WalletSummary<AccountId>) -> u64 {
|
||||
fn next_subtree_index<A: Hash + Eq>(s: &WalletSummary<A>) -> u64 {
|
||||
s.next_sapling_subtree_index()
|
||||
}
|
||||
|
||||
|
@ -517,12 +520,12 @@ pub(crate) mod tests {
|
|||
.map(|n| n.take_sapling())
|
||||
}
|
||||
|
||||
fn decrypted_pool_outputs_count(d_tx: &DecryptedTransaction<'_, AccountId>) -> usize {
|
||||
fn decrypted_pool_outputs_count<A>(d_tx: &DecryptedTransaction<'_, A>) -> usize {
|
||||
d_tx.sapling_outputs().len()
|
||||
}
|
||||
|
||||
fn with_decrypted_pool_memos(
|
||||
d_tx: &DecryptedTransaction<'_, AccountId>,
|
||||
fn with_decrypted_pool_memos<A>(
|
||||
d_tx: &DecryptedTransaction<'_, A>,
|
||||
mut f: impl FnMut(&MemoBytes),
|
||||
) {
|
||||
for output in d_tx.sapling_outputs() {
|
||||
|
|
|
@ -587,7 +587,10 @@ pub(crate) mod tests {
|
|||
use zcash_client_backend::data_api::{
|
||||
chain::{ChainState, CommitmentTreeRoot},
|
||||
scanning::{spanning_tree::testing::scan_range, ScanPriority},
|
||||
testing::{AddressType, FakeCompactOutput, InitialChainState, TestBuilder, TestState},
|
||||
testing::{
|
||||
pool::ShieldedPoolTester, AddressType, FakeCompactOutput, InitialChainState,
|
||||
TestBuilder, TestState,
|
||||
},
|
||||
AccountBirthday, Ratio, WalletRead, WalletWrite, SAPLING_SHARD_HEIGHT,
|
||||
};
|
||||
use zcash_primitives::{
|
||||
|
@ -601,7 +604,6 @@ pub(crate) mod tests {
|
|||
error::SqliteClientError,
|
||||
testing::{
|
||||
db::{TestDb, TestDbFactory},
|
||||
pool::ShieldedPoolTester,
|
||||
BlockCache,
|
||||
},
|
||||
wallet::{
|
||||
|
|
Loading…
Reference in New Issue