diff --git a/Cargo.lock b/Cargo.lock index 9a494eec3d..966e592412 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2695,9 +2695,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.12" +version = "0.23.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" +checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" dependencies = [ "aws-lc-rs", "log", @@ -4270,6 +4270,7 @@ dependencies = [ "hyper-rustls", "hyper-util", "prost", + "rustls", "rustls-pemfile 1.0.4", "thiserror", "tokio-rustls", diff --git a/Cargo.toml b/Cargo.toml index e13d322e99..6d63b19f18 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -71,6 +71,7 @@ rand = "0.8.5" reqwest = "0.12" ring = "0.17.0" rust-embed = "6.3.0" +rustls = { version = "0.23.13", features = ["ring"] } rustls-pemfile = "1.0.0" rustyline = "11.0.0" secp256k1 = "=0.27.0" diff --git a/libtonode-tests/tests/wallet.rs b/libtonode-tests/tests/wallet.rs index 29f04fe599..0ce0669e43 100644 --- a/libtonode-tests/tests/wallet.rs +++ b/libtonode-tests/tests/wallet.rs @@ -18,7 +18,6 @@ mod load_wallet { use zingolib::utils; use zingolib::wallet::disk::testing::examples; use zingolib::wallet::propose::ProposeSendError::Proposal; - use zingolib::wallet::LightWallet; #[tokio::test] async fn load_old_wallet_at_reorged_height() { @@ -74,11 +73,12 @@ mod load_wallet { let _cph = regtest_manager.launch(false).unwrap(); println!("loading wallet"); - let wallet = LightWallet::load_example_wallet(examples::ExampleWalletNetwork::Regtest( + let wallet = examples::ExampleWalletNetwork::Regtest( examples::ExampleRegtestWalletSeed::HMVASMUVWMSSVICHCARBPOCT( - examples::ExampleHMVASMUVWMSSVICHCARBPOCTWalletVersion::V27, + examples::ExampleHMVASMUVWMSSVICHCARBPOCTVersion::V27, ), - )) + ) + .load_example_wallet() .await; // let wallet = zingolib::testutils::load_wallet( diff --git a/zingo-netutils/Cargo.toml b/zingo-netutils/Cargo.toml index 23e50a2211..556299a12d 100644 --- a/zingo-netutils/Cargo.toml +++ b/zingo-netutils/Cargo.toml @@ -12,6 +12,7 @@ hyper-rustls.workspace = true hyper-util.workspace = true hyper.workspace = true prost.workspace = true +rustls.workspace = true rustls-pemfile = { workspace = true } thiserror.workspace = true tokio-rustls.workspace = true diff --git a/zingo-netutils/src/lib.rs b/zingo-netutils/src/lib.rs index 09b0b3ecbd..c93364e424 100644 --- a/zingo-netutils/src/lib.rs +++ b/zingo-netutils/src/lib.rs @@ -85,6 +85,11 @@ impl GrpcConnector { > { let uri = Arc::new(self.uri.clone()); async move { + // install default crypto provider (ring) + if let Err(e) = rustls::crypto::ring::default_provider().install_default() { + eprintln!("Error installing crypto provider: {:?}", e) + }; + let mut http_connector = HttpConnector::new(); http_connector.enforce_http(false); let scheme = uri.scheme().ok_or(GetClientError::InvalidScheme)?.clone(); diff --git a/zingolib/src/config.rs b/zingolib/src/config.rs index 88d9293a95..9611d61c3c 100644 --- a/zingolib/src/config.rs +++ b/zingolib/src/config.rs @@ -259,11 +259,7 @@ impl ZingoConfig { /// create a ZingoConfig that helps a LightClient connect to a server. pub fn create_mainnet() -> ZingoConfig { ZingoConfig::build(ChainType::Mainnet) - .set_lightwalletd_uri( - ("https://zcash.mysideoftheweb.com:19067") - .parse::() - .unwrap(), - ) + .set_lightwalletd_uri(("https://zec.rocks:443").parse::().unwrap()) .create() } diff --git a/zingolib/src/lightclient/send.rs b/zingolib/src/lightclient/send.rs index 006308aac8..4b75be7c3d 100644 --- a/zingolib/src/lightclient/send.rs +++ b/zingolib/src/lightclient/send.rs @@ -318,14 +318,16 @@ pub mod send_with_proposal { #[cfg(all(test, feature = "testvectors"))] mod tests { + use zcash_client_backend::PoolType; + use crate::{ - lightclient::LightClient, - wallet::{ - disk::testing::examples::{ - ExampleMSKMGDBHOTBPETCJWCSPGOPPWalletVersion, ExampleTestnetWalletSeed, - ExampleWalletNetwork, - }, - LightWallet, + lightclient::sync::test::sync_example_wallet, + testutils::chain_generics::{ + conduct_chain::ConductChain as _, live_chain::LiveChain, with_assertions, + }, + wallet::disk::testing::examples::{ + ExampleCBBHRWIILGBRABABSSHSMTPRVersion, ExampleMSKMGDBHOTBPETCJWCSPGOPPVersion, + ExampleTestnetWalletSeed, ExampleWalletNetwork, }, }; @@ -347,17 +349,65 @@ pub mod send_with_proposal { // TODO: match on specific error } - #[ignore] + #[ignore = "live testnet"] + #[tokio::test] + /// this is a live sync test. its execution time scales linearly since last updated + /// this is a live send test. whether it can work depends on the state of live wallet on the blockchain + /// this wallet contains archaic diversified addresses, which may clog the new send engine. + async fn testnet_mskmgdbhotbpetcjwcspgopp_shield_multi_account() { + std::env::set_var("RUST_BACKTRACE", "1"); + let client = crate::lightclient::sync::test::sync_example_wallet( + ExampleWalletNetwork::Testnet(ExampleTestnetWalletSeed::MSKMGDBHOTBPETCJWCSPGOPP( + ExampleMSKMGDBHOTBPETCJWCSPGOPPVersion::Ga74fed621, + )), + ) + .await; + + with_assertions::propose_shield_bump_sync(&mut LiveChain::setup().await, &client, true) + .await; + } + + #[ignore = "live testnet"] + #[tokio::test] + /// this is a live sync test. its execution time scales linearly since last updated + /// this is a live send test. whether it can work depends on the state of live wallet on the blockchain + async fn testnet_cbbhrwiilgbrababsshsmtpr_send_to_self_orchard_hot() { + std::env::set_var("RUST_BACKTRACE", "1"); + let client = sync_example_wallet(ExampleWalletNetwork::Testnet( + ExampleTestnetWalletSeed::CBBHRWIILGBRABABSSHSMTPR( + ExampleCBBHRWIILGBRABABSSHSMTPRVersion::G2f3830058, + ), + )) + .await; + + with_assertions::propose_send_bump_sync_all_recipients( + &mut LiveChain::setup().await, + &client, + vec![( + &client, + PoolType::Shielded(zcash_client_backend::ShieldedProtocol::Orchard), + 10_000, + None, + )], + false, + ) + .await; + } + + #[ignore = "live testnet"] #[tokio::test] - async fn sync_testnet() { - let wallet = LightWallet::load_example_wallet(ExampleWalletNetwork::Testnet( - ExampleTestnetWalletSeed::MSKMGDBHOTBPETCJWCSPGOPP( - ExampleMSKMGDBHOTBPETCJWCSPGOPPWalletVersion::Gab72a38b, + /// this is a live sync test. its execution time scales linearly since last updated + async fn testnet_cbbhrwiilgbrababsshsmtpr_shield_hot() { + std::env::set_var("RUST_BACKTRACE", "1"); + let client = sync_example_wallet(ExampleWalletNetwork::Testnet( + ExampleTestnetWalletSeed::CBBHRWIILGBRABABSSHSMTPR( + ExampleCBBHRWIILGBRABABSSHSMTPRVersion::G2f3830058, ), )) .await; - let lc = LightClient::create_from_wallet_async(wallet).await.unwrap(); - let _ = lc.do_sync(true).await; + + with_assertions::propose_shield_bump_sync(&mut LiveChain::setup().await, &client, true) + .await; } } } diff --git a/zingolib/src/lightclient/sync.rs b/zingolib/src/lightclient/sync.rs index 0849598a92..a7f9bfe638 100644 --- a/zingolib/src/lightclient/sync.rs +++ b/zingolib/src/lightclient/sync.rs @@ -665,3 +665,54 @@ impl LightClient { response } } + +#[cfg(all(test, feature = "testvectors"))] +pub mod test { + use crate::{ + lightclient::LightClient, + wallet::disk::testing::examples::{ + ExampleCBBHRWIILGBRABABSSHSMTPRVersion, ExampleHHCCLALTPCCKCSSLPCNETBLRVersion, + ExampleMSKMGDBHOTBPETCJWCSPGOPPVersion, ExampleMainnetWalletSeed, + ExampleTestnetWalletSeed, ExampleWalletNetwork, + }, + }; + + pub(crate) async fn sync_example_wallet(wallet_case: ExampleWalletNetwork) -> LightClient { + std::env::set_var("RUST_BACKTRACE", "1"); + let wallet = wallet_case.load_example_wallet().await; + let lc = LightClient::create_from_wallet_async(wallet).await.unwrap(); + let _ = lc.do_sync(true).await; + lc + } + + /// this is a live sync test. its execution time scales linearly since last updated + #[tokio::test] + async fn testnet_sync_mskmgdbhotbpetcjwcspgopp_latest() { + sync_example_wallet(ExampleWalletNetwork::Testnet( + ExampleTestnetWalletSeed::MSKMGDBHOTBPETCJWCSPGOPP( + ExampleMSKMGDBHOTBPETCJWCSPGOPPVersion::Ga74fed621, + ), + )) + .await; + } + /// this is a live sync test. its execution time scales linearly since last updated + #[tokio::test] + async fn testnet_sync_cbbhrwiilgbrababsshsmtpr_latest() { + sync_example_wallet(ExampleWalletNetwork::Testnet( + ExampleTestnetWalletSeed::CBBHRWIILGBRABABSSHSMTPR( + ExampleCBBHRWIILGBRABABSSHSMTPRVersion::G2f3830058, + ), + )) + .await; + } + /// this is a live sync test. its execution time scales linearly since last updated + #[tokio::test] + async fn mainnet_sync_hhcclaltpcckcsslpcnetblr_latest() { + sync_example_wallet(ExampleWalletNetwork::Mainnet( + ExampleMainnetWalletSeed::HHCCLALTPCCKCSSLPCNETBLR( + ExampleHHCCLALTPCCKCSSLPCNETBLRVersion::Gf0aaf9347, + ), + )) + .await; + } +} diff --git a/zingolib/src/testutils.rs b/zingolib/src/testutils.rs index d43479575f..354052d20f 100644 --- a/zingolib/src/testutils.rs +++ b/zingolib/src/testutils.rs @@ -16,7 +16,6 @@ pub use incrementalmerkletree; use std::cmp; use std::collections::HashMap; use std::io::Read; -use std::path::{Path, PathBuf}; use std::string::String; use std::sync::atomic::AtomicBool; use std::sync::Arc; @@ -324,26 +323,6 @@ async fn check_wallet_chainheight_value(client: &LightClient, target: u32) -> Re Ok(get_synced_wallet_height(client).await? != target) } -/// TODO: Add Doc Comment Here! -pub fn get_wallet_nym(nym: &str) -> Result<(String, PathBuf, PathBuf), String> { - match nym { - "sap_only" | "orch_only" | "orch_and_sapl" | "tadd_only" => { - let one_sapling_wallet = format!( - "{}/tests/data/wallets/v26/202302_release/regtest/{nym}/zingo-wallet.dat", - paths::get_cargo_manifest_dir().to_string_lossy() - ); - let wallet_path = Path::new(&one_sapling_wallet); - let wallet_dir = wallet_path.parent().unwrap(); - Ok(( - one_sapling_wallet.clone(), - wallet_path.to_path_buf(), - wallet_dir.to_path_buf(), - )) - } - _ => Err(format!("nym {nym} not a valid wallet directory")), - } -} - /// TODO: Add Doc Comment Here! pub struct RecordingReader { from: Reader, diff --git a/zingolib/src/testutils/chain_generics.rs b/zingolib/src/testutils/chain_generics.rs index 3ae89cc39c..3beba2d675 100644 --- a/zingolib/src/testutils/chain_generics.rs +++ b/zingolib/src/testutils/chain_generics.rs @@ -11,7 +11,7 @@ //! - mempool pub mod conduct_chain; +pub mod live_chain; pub mod fixtures; - pub mod with_assertions; diff --git a/zingolib/src/testutils/chain_generics/live_chain.rs b/zingolib/src/testutils/chain_generics/live_chain.rs new file mode 100644 index 0000000000..b25d21d3d6 --- /dev/null +++ b/zingolib/src/testutils/chain_generics/live_chain.rs @@ -0,0 +1,32 @@ +//! implementation of conduct chain for live chains + +use crate::lightclient::LightClient; + +use super::conduct_chain::ConductChain; + +/// this is essentially a placeholder. +/// allows using existing ChainGeneric functions with TestNet wallets +pub struct LiveChain; + +impl ConductChain for LiveChain { + async fn setup() -> Self { + Self {} + } + + async fn create_faucet(&mut self) -> LightClient { + unimplemented!() + } + + fn zingo_config(&mut self) -> crate::config::ZingoConfig { + todo!() + } + + async fn bump_chain(&mut self) { + // average block time is 75 seconds. we do this twice here to insist on a new block + tokio::time::sleep(std::time::Duration::from_secs(150)).await; + } + + fn get_chain_height(&mut self) -> u32 { + unimplemented!() + } +} diff --git a/zingolib/src/testutils/chain_generics/with_assertions.rs b/zingolib/src/testutils/chain_generics/with_assertions.rs index 41dd05731a..c3f0265fcf 100644 --- a/zingolib/src/testutils/chain_generics/with_assertions.rs +++ b/zingolib/src/testutils/chain_generics/with_assertions.rs @@ -43,7 +43,12 @@ where .await .unwrap(); - let send_height = environment.get_chain_height() + 1; + let send_height = sender + .wallet + .get_target_height_and_anchor_offset() + .await + .expect("sender has a target height") + .0; // digesting the calculated transaction // this step happens after transaction is recorded locally, but before learning anything about whether the server accepted it @@ -128,7 +133,13 @@ where { let proposal = client.propose_shield().await.unwrap(); - let send_height = environment.get_chain_height() + 1; + let send_height = client + .wallet + .get_target_height_and_anchor_offset() + .await + .expect("sender has a target height") + .0; + let txids = client .complete_and_broadcast_stored_proposal() .await diff --git a/zingolib/src/wallet/disk/testing/examples.rs b/zingolib/src/wallet/disk/testing/examples.rs index 6cd02605ce..59e8dc1b32 100644 --- a/zingolib/src/wallet/disk/testing/examples.rs +++ b/zingolib/src/wallet/disk/testing/examples.rs @@ -18,32 +18,43 @@ pub enum ExampleWalletNetwork { #[derive(Clone)] pub enum ExampleMainnetWalletSeed { /// this is a mainnet wallet originally called missing_data_test - VTFCORFBCBPCTCFUPMEGMWBP(ExampleVTFCORFBCBPCTCFUPMEGMWBPWalletVersion), + VTFCORFBCBPCTCFUPMEGMWBP(ExampleVTFCORFBCBPCTCFUPMEGMWBPVersion), + /// empty mainnet wallet + HHCCLALTPCCKCSSLPCNETBLR(ExampleHHCCLALTPCCKCSSLPCNETBLRVersion), } /// / #[non_exhaustive] #[derive(Clone)] -pub enum ExampleVTFCORFBCBPCTCFUPMEGMWBPWalletVersion { +pub enum ExampleVTFCORFBCBPCTCFUPMEGMWBPVersion { /// wallet was last saved in this serialization version V28, } /// / #[non_exhaustive] #[derive(Clone)] +pub enum ExampleHHCCLALTPCCKCSSLPCNETBLRVersion { + /// wallet was last saved in this serialization version + Gf0aaf9347, +} +/// / +#[non_exhaustive] +#[derive(Clone)] pub enum ExampleTestnetWalletSeed { - /// This is a testnet seed, generated by fluidvanadium at the beginning of owls (this example wallet enumeration) - MSKMGDBHOTBPETCJWCSPGOPP(ExampleMSKMGDBHOTBPETCJWCSPGOPPWalletVersion), /// this testnet wallet was generated at the beginning of serialization v28 by fluidvanadium - CBBHRWIILGBRABABSSHSMTPR(ExampleCBBHRWIILGBRABABSSHSMTPRWalletVersion), + CBBHRWIILGBRABABSSHSMTPR(ExampleCBBHRWIILGBRABABSSHSMTPRVersion), + /// This is a testnet seed, generated by fluidvanadium at the beginning of owls (this example wallet enumeration) + MSKMGDBHOTBPETCJWCSPGOPP(ExampleMSKMGDBHOTBPETCJWCSPGOPPVersion), } /// / #[non_exhaustive] #[derive(Clone)] -pub enum ExampleMSKMGDBHOTBPETCJWCSPGOPPWalletVersion { +pub enum ExampleMSKMGDBHOTBPETCJWCSPGOPPVersion { /// wallet was last saved by the code in this commit Gab72a38b, /// this wallet was synced in this version. does it have a bunch of taz scattered around different addresses? G93738061a, + /// NU6 added to zingolib re-allows testnet tests by this commit + Ga74fed621, } /// A testnet wallet initiated with /// --seed "chimney better bulb horror rebuild whisper improve intact letter giraffe brave rib appear bulk aim burst snap salt hill sad merge tennis phrase raise" @@ -51,47 +62,59 @@ pub enum ExampleMSKMGDBHOTBPETCJWCSPGOPPWalletVersion { /// including orchard and sapling transactions #[non_exhaustive] #[derive(Clone)] -pub enum ExampleCBBHRWIILGBRABABSSHSMTPRWalletVersion { +pub enum ExampleCBBHRWIILGBRABABSSHSMTPRVersion { /// wallet was last saved in this serialization version V26, /// wallet was last saved in this serialization version V27, /// wallet was last saved in this serialization version V28, + /// wallet was last saved at this commit + G2f3830058, } /// / #[non_exhaustive] #[derive(Clone)] pub enum ExampleRegtestWalletSeed { /// this is a regtest wallet originally called old_wallet_reorg_test_wallet - HMVASMUVWMSSVICHCARBPOCT(ExampleHMVASMUVWMSSVICHCARBPOCTWalletVersion), + HMVASMUVWMSSVICHCARBPOCT(ExampleHMVASMUVWMSSVICHCARBPOCTVersion), /// this is a regtest wallet originally called v26/sap_only - AAAAAAAAAAAAAAAAAAAAAAAA(ExampleAAAAAAAAAAAAAAAAAAAAAAAAWalletVersion), + AAAAAAAAAAAAAAAAAAAAAAAA(ExampleAAAAAAAAAAAAAAAAAAAAAAAAVersion), + /// another regtest wallet + AADAALACAADAALACAADAALAC(ExampleAADAALACAADAALACAADAALACVersion), } /// / #[non_exhaustive] #[derive(Clone)] -pub enum ExampleHMVASMUVWMSSVICHCARBPOCTWalletVersion { +pub enum ExampleHMVASMUVWMSSVICHCARBPOCTVersion { /// wallet was last saved in this serialization version V27, } /// / #[non_exhaustive] #[derive(Clone)] -pub enum ExampleAAAAAAAAAAAAAAAAAAAAAAAAWalletVersion { +pub enum ExampleAAAAAAAAAAAAAAAAAAAAAAAAVersion { /// wallet was last saved in this serialization version V26, } +/// / +#[non_exhaustive] +#[derive(Clone)] +pub enum ExampleAADAALACAADAALACAADAALACVersion { + /// existing receivers? + OrchAndSapl, + /// existing receivers? + OrchOnly, +} -impl LightWallet { +impl ExampleWalletNetwork { /// loads test wallets /// this function can be improved by a macro. even better would be to derive directly from the enum. - // this file is fuc /// loads any one of the test wallets included in the examples - pub async fn load_example_wallet(case: ExampleWalletNetwork) -> Self { - match case { + pub async fn load_example_wallet(&self) -> LightWallet { + match self { ExampleWalletNetwork::Regtest(ExampleRegtestWalletSeed::HMVASMUVWMSSVICHCARBPOCT( - ExampleHMVASMUVWMSSVICHCARBPOCTWalletVersion::V27, + ExampleHMVASMUVWMSSVICHCARBPOCTVersion::V27, )) => { LightWallet::unsafe_from_buffer_regtest(include_bytes!( "examples/regtest/hmvasmuvwmssvichcarbpoct/v27/zingo-wallet.dat" @@ -99,31 +122,31 @@ impl LightWallet { .await } ExampleWalletNetwork::Regtest(ExampleRegtestWalletSeed::AAAAAAAAAAAAAAAAAAAAAAAA( - ExampleAAAAAAAAAAAAAAAAAAAAAAAAWalletVersion::V26, + ExampleAAAAAAAAAAAAAAAAAAAAAAAAVersion::V26, )) => { LightWallet::unsafe_from_buffer_regtest(include_bytes!( "examples/regtest/aaaaaaaaaaaaaaaaaaaaaaaa/v26/zingo-wallet.dat" )) .await } - ExampleWalletNetwork::Testnet(ExampleTestnetWalletSeed::MSKMGDBHOTBPETCJWCSPGOPP( - ExampleMSKMGDBHOTBPETCJWCSPGOPPWalletVersion::Gab72a38b, + ExampleWalletNetwork::Regtest(ExampleRegtestWalletSeed::AADAALACAADAALACAADAALAC( + ExampleAADAALACAADAALACAADAALACVersion::OrchAndSapl, )) => { - LightWallet::unsafe_from_buffer_testnet(include_bytes!( - "examples/testnet/mskmgdbhotbpetcjwcspgopp/Gab72a38b/zingo-wallet.dat" + LightWallet::unsafe_from_buffer_regtest(include_bytes!( + "examples/regtest/aadaalacaadaalacaadaalac/orch_and_sapl/zingo-wallet.dat" )) .await } - ExampleWalletNetwork::Testnet(ExampleTestnetWalletSeed::MSKMGDBHOTBPETCJWCSPGOPP( - ExampleMSKMGDBHOTBPETCJWCSPGOPPWalletVersion::G93738061a, + ExampleWalletNetwork::Regtest(ExampleRegtestWalletSeed::AADAALACAADAALACAADAALAC( + ExampleAADAALACAADAALACAADAALACVersion::OrchOnly, )) => { - LightWallet::unsafe_from_buffer_testnet(include_bytes!( - "examples/testnet/mskmgdbhotbpetcjwcspgopp/G93738061a/zingo-wallet.dat" + LightWallet::unsafe_from_buffer_regtest(include_bytes!( + "examples/regtest/aadaalacaadaalacaadaalac/orch_only/zingo-wallet.dat" )) .await } ExampleWalletNetwork::Testnet(ExampleTestnetWalletSeed::CBBHRWIILGBRABABSSHSMTPR( - ExampleCBBHRWIILGBRABABSSHSMTPRWalletVersion::V26, + ExampleCBBHRWIILGBRABABSSHSMTPRVersion::V26, )) => { LightWallet::unsafe_from_buffer_testnet(include_bytes!( "examples/testnet/cbbhrwiilgbrababsshsmtpr/v26/zingo-wallet.dat" @@ -131,7 +154,7 @@ impl LightWallet { .await } ExampleWalletNetwork::Testnet(ExampleTestnetWalletSeed::CBBHRWIILGBRABABSSHSMTPR( - ExampleCBBHRWIILGBRABABSSHSMTPRWalletVersion::V27, + ExampleCBBHRWIILGBRABABSSHSMTPRVersion::V27, )) => { LightWallet::unsafe_from_buffer_testnet(include_bytes!( "examples/testnet/cbbhrwiilgbrababsshsmtpr/v27/zingo-wallet.dat" @@ -139,21 +162,87 @@ impl LightWallet { .await } ExampleWalletNetwork::Testnet(ExampleTestnetWalletSeed::CBBHRWIILGBRABABSSHSMTPR( - ExampleCBBHRWIILGBRABABSSHSMTPRWalletVersion::V28, + ExampleCBBHRWIILGBRABABSSHSMTPRVersion::V28, )) => { LightWallet::unsafe_from_buffer_testnet(include_bytes!( "examples/testnet/cbbhrwiilgbrababsshsmtpr/v28/zingo-wallet.dat" )) .await } + ExampleWalletNetwork::Testnet(ExampleTestnetWalletSeed::CBBHRWIILGBRABABSSHSMTPR( + ExampleCBBHRWIILGBRABABSSHSMTPRVersion::G2f3830058, + )) => { + LightWallet::unsafe_from_buffer_testnet(include_bytes!( + "examples/testnet/cbbhrwiilgbrababsshsmtpr/G2f3830058/zingo-wallet.dat" + )) + .await + } + ExampleWalletNetwork::Testnet(ExampleTestnetWalletSeed::MSKMGDBHOTBPETCJWCSPGOPP( + ExampleMSKMGDBHOTBPETCJWCSPGOPPVersion::Gab72a38b, + )) => { + LightWallet::unsafe_from_buffer_testnet(include_bytes!( + "examples/testnet/mskmgdbhotbpetcjwcspgopp/Gab72a38b/zingo-wallet.dat" + )) + .await + } + ExampleWalletNetwork::Testnet(ExampleTestnetWalletSeed::MSKMGDBHOTBPETCJWCSPGOPP( + ExampleMSKMGDBHOTBPETCJWCSPGOPPVersion::G93738061a, + )) => { + LightWallet::unsafe_from_buffer_testnet(include_bytes!( + "examples/testnet/mskmgdbhotbpetcjwcspgopp/G93738061a/zingo-wallet.dat" + )) + .await + } + ExampleWalletNetwork::Testnet(ExampleTestnetWalletSeed::MSKMGDBHOTBPETCJWCSPGOPP( + ExampleMSKMGDBHOTBPETCJWCSPGOPPVersion::Ga74fed621, + )) => { + LightWallet::unsafe_from_buffer_testnet(include_bytes!( + "examples/testnet/mskmgdbhotbpetcjwcspgopp/Ga74fed621/zingo-wallet.dat" + )) + .await + } ExampleWalletNetwork::Mainnet(ExampleMainnetWalletSeed::VTFCORFBCBPCTCFUPMEGMWBP( - ExampleVTFCORFBCBPCTCFUPMEGMWBPWalletVersion::V28, + ExampleVTFCORFBCBPCTCFUPMEGMWBPVersion::V28, )) => { LightWallet::unsafe_from_buffer_mainnet(include_bytes!( "examples/mainnet/vtfcorfbcbpctcfupmegmwbp/v28/zingo-wallet.dat" )) .await } + ExampleWalletNetwork::Mainnet(ExampleMainnetWalletSeed::HHCCLALTPCCKCSSLPCNETBLR( + ExampleHHCCLALTPCCKCSSLPCNETBLRVersion::Gf0aaf9347, + )) => { + LightWallet::unsafe_from_buffer_mainnet(include_bytes!( + "examples/mainnet/hhcclaltpcckcsslpcnetblr/gf0aaf9347/zingo-wallet.dat" + )) + .await + } + } + } + /// picks the seed (or ufvk) string associated with an example wallet + pub async fn example_wallet_base(&self) -> String { + match self { + ExampleWalletNetwork::Regtest(ExampleRegtestWalletSeed::HMVASMUVWMSSVICHCARBPOCT( + _, + )) => crate::testvectors::seeds::HOSPITAL_MUSEUM_SEED.to_string(), + ExampleWalletNetwork::Regtest(ExampleRegtestWalletSeed::AAAAAAAAAAAAAAAAAAAAAAAA( + _, + )) => crate::testvectors::seeds::ABANDON_ART_SEED.to_string(), + ExampleWalletNetwork::Regtest(ExampleRegtestWalletSeed::AADAALACAADAALACAADAALAC( + _, + )) => "absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice comic".to_string(), + ExampleWalletNetwork::Testnet(ExampleTestnetWalletSeed::CBBHRWIILGBRABABSSHSMTPR( + _, + )) => crate::testvectors::seeds::CHIMNEY_BETTER_SEED.to_string(), + ExampleWalletNetwork::Testnet(ExampleTestnetWalletSeed::MSKMGDBHOTBPETCJWCSPGOPP( + _, + )) => "mobile shuffle keen mother globe desk bless hub oil town begin potato explain table crawl just wild click spring pottery gasp often pill plug".to_string(), + ExampleWalletNetwork::Mainnet(ExampleMainnetWalletSeed::VTFCORFBCBPCTCFUPMEGMWBP( + _, + )) => "village target fun course orange release female brain cruise birth pet copy trouble common fitness unfold panther man enjoy genuine merry write bulb pledge".to_string(), + ExampleWalletNetwork::Mainnet(ExampleMainnetWalletSeed::HHCCLALTPCCKCSSLPCNETBLR( + _, + )) => "hotel humor crunch crack language awkward lunar term priority critic cushion keep coin sketch soap laugh pretty cement noodle enjoy trip bicycle list return".to_string(), } } } diff --git a/zingolib/src/wallet/disk/testing/examples/mainnet/hhcclaltpcckcsslpcnetblr/gf0aaf9347/zingo-wallet.dat b/zingolib/src/wallet/disk/testing/examples/mainnet/hhcclaltpcckcsslpcnetblr/gf0aaf9347/zingo-wallet.dat new file mode 100644 index 0000000000..97d61e5f45 Binary files /dev/null and b/zingolib/src/wallet/disk/testing/examples/mainnet/hhcclaltpcckcsslpcnetblr/gf0aaf9347/zingo-wallet.dat differ diff --git a/zingolib/src/wallet/disk/testing/examples/regtest/hmvasmuvwmssvichcarbpoct/v26/zingo-wallet.dat b/zingolib/src/wallet/disk/testing/examples/regtest/hmvasmuvwmssvichcarbpoct/v26/zingo-wallet.dat deleted file mode 100644 index 67758acfd8..0000000000 Binary files a/zingolib/src/wallet/disk/testing/examples/regtest/hmvasmuvwmssvichcarbpoct/v26/zingo-wallet.dat and /dev/null differ diff --git a/zingolib/src/wallet/disk/testing/examples/testnet/cbbhrwiilgbrababsshsmtpr/G2f3830058/zingo-wallet.dat b/zingolib/src/wallet/disk/testing/examples/testnet/cbbhrwiilgbrababsshsmtpr/G2f3830058/zingo-wallet.dat new file mode 100644 index 0000000000..851c287d35 Binary files /dev/null and b/zingolib/src/wallet/disk/testing/examples/testnet/cbbhrwiilgbrababsshsmtpr/G2f3830058/zingo-wallet.dat differ diff --git a/zingolib/src/wallet/disk/testing/examples/testnet/mskmgdbhotbpetcjwcspgopp/Ga74fed621/zingo-wallet.dat b/zingolib/src/wallet/disk/testing/examples/testnet/mskmgdbhotbpetcjwcspgopp/Ga74fed621/zingo-wallet.dat new file mode 100644 index 0000000000..b9481078d1 Binary files /dev/null and b/zingolib/src/wallet/disk/testing/examples/testnet/mskmgdbhotbpetcjwcspgopp/Ga74fed621/zingo-wallet.dat differ diff --git a/zingolib/src/wallet/disk/testing/examples/v26/202302_release/mainnet/zingo-wallet.dat b/zingolib/src/wallet/disk/testing/examples/v26/202302_release/mainnet/zingo-wallet.dat deleted file mode 100644 index 0d360b81d1..0000000000 Binary files a/zingolib/src/wallet/disk/testing/examples/v26/202302_release/mainnet/zingo-wallet.dat and /dev/null differ diff --git a/zingolib/src/wallet/disk/testing/tests.rs b/zingolib/src/wallet/disk/testing/tests.rs index 99518a8428..98ba1c299d 100644 --- a/zingolib/src/wallet/disk/testing/tests.rs +++ b/zingolib/src/wallet/disk/testing/tests.rs @@ -5,61 +5,79 @@ use crate::get_base_address_macro; use crate::lightclient::LightClient; use super::super::LightWallet; +use super::assert_wallet_capability_matches_seed; +use super::examples::ExampleWalletNetwork; use super::examples::ExampleWalletNetwork::Mainnet; use super::examples::ExampleWalletNetwork::Regtest; use super::examples::ExampleWalletNetwork::Testnet; +use super::examples::ExampleMainnetWalletSeed::HHCCLALTPCCKCSSLPCNETBLR; use super::examples::ExampleMainnetWalletSeed::VTFCORFBCBPCTCFUPMEGMWBP; use super::examples::ExampleRegtestWalletSeed::AAAAAAAAAAAAAAAAAAAAAAAA; +use super::examples::ExampleRegtestWalletSeed::AADAALACAADAALACAADAALAC; use super::examples::ExampleRegtestWalletSeed::HMVASMUVWMSSVICHCARBPOCT; use super::examples::ExampleTestnetWalletSeed::CBBHRWIILGBRABABSSHSMTPR; use super::examples::ExampleTestnetWalletSeed::MSKMGDBHOTBPETCJWCSPGOPP; -use super::examples::ExampleAAAAAAAAAAAAAAAAAAAAAAAAWalletVersion; -use super::examples::ExampleCBBHRWIILGBRABABSSHSMTPRWalletVersion; -use super::examples::ExampleHMVASMUVWMSSVICHCARBPOCTWalletVersion; -use super::examples::ExampleMSKMGDBHOTBPETCJWCSPGOPPWalletVersion; -use super::examples::ExampleVTFCORFBCBPCTCFUPMEGMWBPWalletVersion; +use super::examples::ExampleAAAAAAAAAAAAAAAAAAAAAAAAVersion; +use super::examples::ExampleAADAALACAADAALACAADAALACVersion; +use super::examples::ExampleCBBHRWIILGBRABABSSHSMTPRVersion; +use super::examples::ExampleHHCCLALTPCCKCSSLPCNETBLRVersion; +use super::examples::ExampleHMVASMUVWMSSVICHCARBPOCTVersion; +use super::examples::ExampleMSKMGDBHOTBPETCJWCSPGOPPVersion; +use super::examples::ExampleVTFCORFBCBPCTCFUPMEGMWBPVersion; // moving toward completeness: each of these tests should assert everything known about the LightWallet without network. +impl ExampleWalletNetwork { + /// this is enough data to restore wallet from! thus, it is the bronze test for backward compatibility + async fn load_example_wallet_with_seed_verification(&self) -> LightWallet { + let wallet = self.load_example_wallet().await; + assert_wallet_capability_matches_seed(&wallet, self.example_wallet_base().await).await; + wallet + } +} + #[tokio::test] -async fn verify_example_wallet_regtest_hmvasmuvwmssvichcarbpoct_v27() { - let _wallet = LightWallet::load_example_wallet(Regtest(HMVASMUVWMSSVICHCARBPOCT( - ExampleHMVASMUVWMSSVICHCARBPOCTWalletVersion::V27, - ))) +async fn verify_example_wallet_regtest_aaaaaaaaaaaaaaaaaaaaaaaa_v26() { + Regtest(AAAAAAAAAAAAAAAAAAAAAAAA( + ExampleAAAAAAAAAAAAAAAAAAAAAAAAVersion::V26, + )) + .load_example_wallet_with_seed_verification() .await; } -#[ignore = "test fails because ZFZ panics in regtest"] #[tokio::test] -async fn verify_example_wallet_regtest_aaaaaaaaaaaaaaaaaaaaaaaa_v26() { - let wallet = LightWallet::load_example_wallet(Regtest(AAAAAAAAAAAAAAAAAAAAAAAA( - ExampleAAAAAAAAAAAAAAAAAAAAAAAAWalletVersion::V26, - ))) +async fn verify_example_wallet_regtest_aadaalacaadaalacaadaalac_orch_and_sapl() { + Regtest(AADAALACAADAALACAADAALAC( + ExampleAADAALACAADAALACAADAALACVersion::OrchAndSapl, + )) + .load_example_wallet_with_seed_verification() .await; - - loaded_wallet_assert( - wallet, - crate::testvectors::seeds::CHIMNEY_BETTER_SEED.to_string(), - 10342837, - 3, - ) +} +#[tokio::test] +async fn verify_example_wallet_regtest_aadaalacaadaalacaadaalac_orch_only() { + Regtest(AADAALACAADAALACAADAALAC( + ExampleAADAALACAADAALACAADAALACVersion::OrchOnly, + )) + .load_example_wallet_with_seed_verification() .await; } - #[tokio::test] -async fn verify_example_wallet_testnet_mskmgdbhotbpetcjwcspgopp_gab72a38b() { - let _wallet = LightWallet::load_example_wallet(Testnet(MSKMGDBHOTBPETCJWCSPGOPP( - ExampleMSKMGDBHOTBPETCJWCSPGOPPWalletVersion::Gab72a38b, - ))) +async fn verify_example_wallet_regtest_hmvasmuvwmssvichcarbpoct_v27() { + Regtest(HMVASMUVWMSSVICHCARBPOCT( + ExampleHMVASMUVWMSSVICHCARBPOCTVersion::V27, + )) + .load_example_wallet_with_seed_verification() .await; } +/// unlike other, more basic tests, this test also checks number of addresses and balance #[tokio::test] async fn verify_example_wallet_testnet_cbbhrwiilgbrababsshsmtpr_v26() { - let wallet = LightWallet::load_example_wallet(Testnet(CBBHRWIILGBRABABSSHSMTPR( - ExampleCBBHRWIILGBRABABSSHSMTPRWalletVersion::V26, - ))) + let wallet = Testnet(CBBHRWIILGBRABABSSHSMTPR( + ExampleCBBHRWIILGBRABABSSHSMTPRVersion::V26, + )) + .load_example_wallet_with_seed_verification() .await; loaded_wallet_assert( @@ -70,12 +88,14 @@ async fn verify_example_wallet_testnet_cbbhrwiilgbrababsshsmtpr_v26() { ) .await; } +/// unlike other, more basic tests, this test also checks number of addresses and balance #[ignore = "test proves note has no index bug is a breaker"] #[tokio::test] async fn verify_example_wallet_testnet_cbbhrwiilgbrababsshsmtpr_v27() { - let wallet = LightWallet::load_example_wallet(Testnet(CBBHRWIILGBRABABSSHSMTPR( - ExampleCBBHRWIILGBRABABSSHSMTPRWalletVersion::V27, - ))) + let wallet = Testnet(CBBHRWIILGBRABABSSHSMTPR( + ExampleCBBHRWIILGBRABABSSHSMTPRVersion::V27, + )) + .load_example_wallet_with_seed_verification() .await; loaded_wallet_assert( @@ -88,16 +108,58 @@ async fn verify_example_wallet_testnet_cbbhrwiilgbrababsshsmtpr_v27() { } #[tokio::test] async fn verify_example_wallet_testnet_cbbhrwiilgbrababsshsmtpr_v28() { - let _wallet = LightWallet::load_example_wallet(Testnet(CBBHRWIILGBRABABSSHSMTPR( - ExampleCBBHRWIILGBRABABSSHSMTPRWalletVersion::V28, - ))) + Testnet(CBBHRWIILGBRABABSSHSMTPR( + ExampleCBBHRWIILGBRABABSSHSMTPRVersion::V28, + )) + .load_example_wallet_with_seed_verification() + .await; +} +#[tokio::test] +async fn verify_example_wallet_testnet_cbbhrwiilgbrababsshsmtpr_g2f3830058() { + Testnet(CBBHRWIILGBRABABSSHSMTPR( + ExampleCBBHRWIILGBRABABSSHSMTPRVersion::G2f3830058, + )) + .load_example_wallet_with_seed_verification() + .await; +} +#[tokio::test] +async fn verify_example_wallet_testnet_mskmgdbhotbpetcjwcspgopp_gab72a38b() { + Testnet(MSKMGDBHOTBPETCJWCSPGOPP( + ExampleMSKMGDBHOTBPETCJWCSPGOPPVersion::Gab72a38b, + )) + .load_example_wallet_with_seed_verification() + .await; +} +#[tokio::test] +async fn verify_example_wallet_testnet_mskmgdbhotbpetcjwcspgopp_g93738061a() { + Testnet(MSKMGDBHOTBPETCJWCSPGOPP( + ExampleMSKMGDBHOTBPETCJWCSPGOPPVersion::G93738061a, + )) + .load_example_wallet_with_seed_verification() + .await; +} +#[tokio::test] +async fn verify_example_wallet_testnet_mskmgdbhotbpetcjwcspgopp_ga74fed621() { + Testnet(MSKMGDBHOTBPETCJWCSPGOPP( + ExampleMSKMGDBHOTBPETCJWCSPGOPPVersion::Ga74fed621, + )) + .load_example_wallet_with_seed_verification() .await; } #[tokio::test] async fn verify_example_wallet_mainnet_vtfcorfbcbpctcfupmegmwbp_v28() { - let _wallet = LightWallet::load_example_wallet(Mainnet(VTFCORFBCBPCTCFUPMEGMWBP( - ExampleVTFCORFBCBPCTCFUPMEGMWBPWalletVersion::V28, - ))) + Mainnet(VTFCORFBCBPCTCFUPMEGMWBP( + ExampleVTFCORFBCBPCTCFUPMEGMWBPVersion::V28, + )) + .load_example_wallet_with_seed_verification() + .await; +} +#[tokio::test] +async fn verify_example_wallet_mainnet_hhcclaltpcckcsslpcnetblr_gf0aaf9347() { + Mainnet(HHCCLALTPCCKCSSLPCNETBLR( + ExampleHHCCLALTPCCKCSSLPCNETBLRVersion::Gf0aaf9347, + )) + .load_example_wallet_with_seed_verification() .await; } @@ -107,52 +169,9 @@ async fn loaded_wallet_assert( expected_balance: u64, expected_num_addresses: usize, ) { - let expected_mnemonic = ( - Mnemonic::::from_phrase(expected_seed_phrase).unwrap(), - 0, - ); + assert_wallet_capability_matches_seed(&wallet, expected_seed_phrase).await; - let expected_wc = crate::wallet::keys::unified::WalletCapability::new_from_phrase( - &wallet.transaction_context.config, - &expected_mnemonic.0, - expected_mnemonic.1, - ) - .unwrap(); let wc = wallet.wallet_capability(); - - // We don't want the WalletCapability to impl. `Eq` (because it stores secret keys) - // so we have to compare each component instead - - // Compare Orchard - let crate::wallet::keys::unified::Capability::Spend(orchard_sk) = &wc.orchard else { - panic!("Expected Orchard Spending Key"); - }; - assert_eq!( - orchard_sk.to_bytes(), - orchard::keys::SpendingKey::try_from(&expected_wc) - .unwrap() - .to_bytes() - ); - - // Compare Sapling - let crate::wallet::keys::unified::Capability::Spend(sapling_sk) = &wc.sapling else { - panic!("Expected Sapling Spending Key"); - }; - assert_eq!( - sapling_sk, - &zcash_client_backend::keys::sapling::ExtendedSpendingKey::try_from(&expected_wc).unwrap() - ); - - // Compare transparent - let crate::wallet::keys::unified::Capability::Spend(transparent_sk) = &wc.transparent else { - panic!("Expected transparent extended private key"); - }; - assert_eq!( - transparent_sk, - &crate::wallet::keys::extended_transparent::ExtendedPrivKey::try_from(&expected_wc) - .unwrap() - ); - assert_eq!(wc.addresses().len(), expected_num_addresses); for addr in wc.addresses().iter() { assert!(addr.orchard().is_some()); @@ -186,6 +205,7 @@ async fn loaded_wallet_assert( } } +// todo: proptest enum #[tokio::test] async fn reload_wallet_from_buffer() { use zcash_primitives::consensus::Parameters; @@ -196,9 +216,10 @@ async fn reload_wallet_from_buffer() { use crate::wallet::WalletBase; use crate::wallet::WalletCapability; - let mid_wallet = LightWallet::load_example_wallet(Testnet(CBBHRWIILGBRABABSSHSMTPR( - ExampleCBBHRWIILGBRABABSSHSMTPRWalletVersion::V28, - ))) + let mid_wallet = Testnet(CBBHRWIILGBRABABSSHSMTPR( + ExampleCBBHRWIILGBRABABSSHSMTPRVersion::V28, + )) + .load_example_wallet_with_seed_verification() .await; let mid_client = LightClient::create_from_wallet_async(mid_wallet) diff --git a/zingolib/src/wallet/send.rs b/zingolib/src/wallet/send.rs index c742edcfd8..08b95b3c0e 100644 --- a/zingolib/src/wallet/send.rs +++ b/zingolib/src/wallet/send.rs @@ -48,7 +48,7 @@ impl SendProgress { impl LightWallet { /// Determines the target height for a transaction, and the offset from which to /// select anchors, based on the current synchronised block chain. - pub(super) async fn get_target_height_and_anchor_offset(&self) -> Option<(u32, usize)> { + pub(crate) async fn get_target_height_and_anchor_offset(&self) -> Option<(u32, usize)> { let range = { let blocks = self.blocks.read().await; ( @@ -137,6 +137,7 @@ impl LightWallet { .map_err(BuildTransactionError::SaplingParams)?; let sapling_prover = zcash_proofs::prover::LocalTxProver::from_bytes(&sapling_spend, &sapling_output); + let unified_spend_key = UnifiedSpendingKey::try_from(self.wallet_capability().as_ref()) .map_err(BuildTransactionError::UnifiedSpendKey)?;