Add a test for unified address derivation.
This commit is contained in:
parent
34a7abd653
commit
bd8472535c
|
@ -260,7 +260,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn ua_parsing() {
|
fn ua_parsing() {
|
||||||
for tv in test_vectors::UNIFIED {
|
for tv in test_vectors::UNIFIED {
|
||||||
match RecipientAddress::decode(&MAIN_NETWORK, &tv.unified_addr) {
|
match RecipientAddress::decode(&MAIN_NETWORK, tv.unified_addr) {
|
||||||
Some(RecipientAddress::Unified(ua)) => {
|
Some(RecipientAddress::Unified(ua)) => {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
ua.transparent().is_some(),
|
ua.transparent().is_some(),
|
||||||
|
|
|
@ -591,10 +591,14 @@ mod tests {
|
||||||
|
|
||||||
#[cfg(feature = "transparent-inputs")]
|
#[cfg(feature = "transparent-inputs")]
|
||||||
use {
|
use {
|
||||||
crate::encoding::AddressCodec,
|
crate::{address::RecipientAddress, encoding::AddressCodec},
|
||||||
zcash_primitives::legacy::{
|
zcash_address::test_vectors,
|
||||||
self,
|
zcash_primitives::{
|
||||||
keys::{AccountPrivKey, IncomingViewingKey},
|
legacy::{
|
||||||
|
self,
|
||||||
|
keys::{AccountPrivKey, IncomingViewingKey},
|
||||||
|
},
|
||||||
|
zip32::DiversifierIndex,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -699,6 +703,50 @@ mod tests {
|
||||||
assert_eq!(decoded_with_t.unknown.len(), 1);
|
assert_eq!(decoded_with_t.unknown.len(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "transparent-inputs")]
|
||||||
|
fn ufvk_derivation() {
|
||||||
|
for tv in test_vectors::UNIFIED {
|
||||||
|
let usk = UnifiedSpendingKey::from_seed(
|
||||||
|
&MAIN_NETWORK,
|
||||||
|
&tv.root_seed,
|
||||||
|
AccountId::from(tv.account),
|
||||||
|
)
|
||||||
|
.expect("seed produced a valid unified spending key");
|
||||||
|
|
||||||
|
let d_idx = DiversifierIndex::from(tv.diversifier_index);
|
||||||
|
let ufvk = usk.to_unified_full_viewing_key();
|
||||||
|
|
||||||
|
// The test vectors contain some diversifier indices that do not generate
|
||||||
|
// valid Sapling addresses, so skip those.
|
||||||
|
if ufvk.sapling().unwrap().address(d_idx).is_none() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let ua = ufvk.address(d_idx).unwrap_or_else(|| panic!("diversifier index {} should have produced a valid unified address for account {}",
|
||||||
|
tv.diversifier_index, tv.account));
|
||||||
|
|
||||||
|
match RecipientAddress::decode(&MAIN_NETWORK, tv.unified_addr) {
|
||||||
|
Some(RecipientAddress::Unified(tvua)) => {
|
||||||
|
// We always derive transparent and Sapling receivers, but not
|
||||||
|
// every value in the test vectors have these present.
|
||||||
|
if tvua.transparent().is_some() {
|
||||||
|
assert_eq!(tvua.transparent(), ua.transparent());
|
||||||
|
}
|
||||||
|
if tvua.sapling().is_some() {
|
||||||
|
assert_eq!(tvua.sapling(), ua.sapling());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_other => {
|
||||||
|
panic!(
|
||||||
|
"{} did not decode to a valid unified address",
|
||||||
|
tv.unified_addr
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
proptest! {
|
proptest! {
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "unstable")]
|
#[cfg(feature = "unstable")]
|
||||||
|
|
|
@ -37,6 +37,7 @@ regex = "1.4"
|
||||||
tempfile = "3"
|
tempfile = "3"
|
||||||
zcash_proofs = { version = "0.7", path = "../zcash_proofs" }
|
zcash_proofs = { version = "0.7", path = "../zcash_proofs" }
|
||||||
zcash_primitives = { version = "0.7", path = "../zcash_primitives", features = ["test-dependencies"] }
|
zcash_primitives = { version = "0.7", path = "../zcash_primitives", features = ["test-dependencies"] }
|
||||||
|
zcash_address = { version = "0.1", path = "../components/zcash_address", features = ["test-dependencies"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
mainnet = []
|
mainnet = []
|
||||||
|
|
|
@ -288,6 +288,8 @@ mod tests {
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use tempfile::NamedTempFile;
|
use tempfile::NamedTempFile;
|
||||||
|
|
||||||
|
use zcash_address::test_vectors;
|
||||||
|
|
||||||
use zcash_client_backend::{
|
use zcash_client_backend::{
|
||||||
address::RecipientAddress,
|
address::RecipientAddress,
|
||||||
encoding::{encode_extended_full_viewing_key, encode_payment_address},
|
encoding::{encode_extended_full_viewing_key, encode_payment_address},
|
||||||
|
@ -296,16 +298,19 @@ mod tests {
|
||||||
|
|
||||||
use zcash_primitives::{
|
use zcash_primitives::{
|
||||||
block::BlockHash,
|
block::BlockHash,
|
||||||
consensus::{BlockHeight, BranchId, Parameters},
|
consensus::{BlockHeight, BranchId, Network, Parameters},
|
||||||
transaction::{TransactionData, TxVersion},
|
transaction::{TransactionData, TxVersion},
|
||||||
zip32::sapling::{DiversifiableFullViewingKey, ExtendedFullViewingKey},
|
zip32::{
|
||||||
|
sapling::{DiversifiableFullViewingKey, ExtendedFullViewingKey},
|
||||||
|
DiversifierIndex,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::SqliteClientError,
|
error::SqliteClientError,
|
||||||
tests::{self, network},
|
tests::{self, network},
|
||||||
wallet::get_address,
|
wallet::{self, get_address},
|
||||||
AccountId, WalletDb,
|
AccountId, WalletDb, WalletWrite,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{init_accounts_table, init_blocks_table, init_wallet_db};
|
use super::{init_accounts_table, init_blocks_table, init_wallet_db};
|
||||||
|
@ -1056,7 +1061,7 @@ mod tests {
|
||||||
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(), tests::network()).unwrap();
|
let mut db_data = WalletDb::for_path(data_file.path(), tests::network()).unwrap();
|
||||||
init_wallet_db(&mut db_data, Some(Secret::new(vec![]))).unwrap();
|
init_wallet_db(&mut db_data, None).unwrap();
|
||||||
|
|
||||||
let seed = [0u8; 32];
|
let seed = [0u8; 32];
|
||||||
|
|
||||||
|
@ -1072,4 +1077,40 @@ mod tests {
|
||||||
let pa = get_address(&db_data, AccountId::from(0)).unwrap();
|
let pa = get_address(&db_data, AccountId::from(0)).unwrap();
|
||||||
assert_eq!(pa.unwrap(), expected_address);
|
assert_eq!(pa.unwrap(), expected_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "transparent-inputs")]
|
||||||
|
fn account_produces_expected_ua_sequence() {
|
||||||
|
let data_file = NamedTempFile::new().unwrap();
|
||||||
|
let mut db_data = WalletDb::for_path(data_file.path(), Network::MainNetwork).unwrap();
|
||||||
|
init_wallet_db(&mut db_data, None).unwrap();
|
||||||
|
|
||||||
|
let mut ops = db_data.get_update_ops().unwrap();
|
||||||
|
let seed = test_vectors::UNIFIED[0].root_seed;
|
||||||
|
let (account, _usk) = ops.create_account(&Secret::new(seed.to_vec())).unwrap();
|
||||||
|
assert_eq!(account, AccountId::from(0u32));
|
||||||
|
|
||||||
|
for tv in &test_vectors::UNIFIED[..3] {
|
||||||
|
if let Some(RecipientAddress::Unified(tvua)) =
|
||||||
|
RecipientAddress::decode(&Network::MainNetwork, tv.unified_addr)
|
||||||
|
{
|
||||||
|
let (ua, di) = wallet::get_current_address(&db_data, account)
|
||||||
|
.unwrap()
|
||||||
|
.expect("create_account generated the first address");
|
||||||
|
assert_eq!(DiversifierIndex::from(tv.diversifier_index), di);
|
||||||
|
assert_eq!(tvua.transparent(), ua.transparent());
|
||||||
|
assert_eq!(tvua.sapling(), ua.sapling());
|
||||||
|
assert_eq!(tv.unified_addr, ua.encode(&Network::MainNetwork));
|
||||||
|
|
||||||
|
ops.get_next_available_address(account)
|
||||||
|
.unwrap()
|
||||||
|
.expect("get_next_available_address generated an address");
|
||||||
|
} else {
|
||||||
|
panic!(
|
||||||
|
"{} did not decode to a valid unified address",
|
||||||
|
tv.unified_addr
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue