From d362da85c8527e5e6aee51293426a3881c5b1179 Mon Sep 17 00:00:00 2001 From: fluidvanadium Date: Mon, 12 Aug 2024 21:06:23 +0000 Subject: [PATCH 01/13] stub assert_test_wallet fn --- zingolib/src/wallet/disk/testing.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/zingolib/src/wallet/disk/testing.rs b/zingolib/src/wallet/disk/testing.rs index 0545fedf0..c381ce6b5 100644 --- a/zingolib/src/wallet/disk/testing.rs +++ b/zingolib/src/wallet/disk/testing.rs @@ -32,6 +32,10 @@ impl LightWallet { } } +async fn assert_test_wallet(case: examples::LegacyWalletCase) { + let wallet = LightWallet::load_example_wallet(case).await; +} + /// example wallets /// including from different versions of the software. pub mod examples; From f59d520a37644c71e603ff0107a5e6f9b1469dbc Mon Sep 17 00:00:00 2001 From: fluidvanadium Date: Mon, 12 Aug 2024 21:24:52 +0000 Subject: [PATCH 02/13] helperized expected balance --- zingolib/src/wallet/disk/testing.rs | 6 +++--- zingolib/src/wallet/disk/testing/examples.rs | 13 ++++++++++++ zingolib/src/wallet/disk/testing/tests.rs | 22 +++++++++++--------- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/zingolib/src/wallet/disk/testing.rs b/zingolib/src/wallet/disk/testing.rs index c381ce6b5..6ef9d29d4 100644 --- a/zingolib/src/wallet/disk/testing.rs +++ b/zingolib/src/wallet/disk/testing.rs @@ -32,9 +32,9 @@ impl LightWallet { } } -async fn assert_test_wallet(case: examples::LegacyWalletCase) { - let wallet = LightWallet::load_example_wallet(case).await; -} +// async fn assert_test_wallet(case: examples::LegacyWalletCase) { +// let wallet = LightWallet::load_example_wallet(case).await; +// } /// example wallets /// including from different versions of the software. diff --git a/zingolib/src/wallet/disk/testing/examples.rs b/zingolib/src/wallet/disk/testing/examples.rs index 9d808ea64..a1462ed6b 100644 --- a/zingolib/src/wallet/disk/testing/examples.rs +++ b/zingolib/src/wallet/disk/testing/examples.rs @@ -3,6 +3,7 @@ use super::super::LightWallet; /// i do not know the difference between these wallets but i will find out soon /// what can these files do? #[non_exhaustive] +#[derive(Clone)] pub enum LegacyWalletCaseZingoV26 { /// / One, @@ -13,6 +14,7 @@ pub enum LegacyWalletCaseZingoV26 { } /// an enumeration of cases to test #[non_exhaustive] +#[derive(Clone)] pub enum LegacyWalletCase { /// at this version, legacy testing began ZingoV26(LegacyWalletCaseZingoV26), @@ -59,4 +61,15 @@ impl LightWallet { } } } + + /// each wallet file has a saved balance + pub fn example_expected_balance(case: LegacyWalletCase) -> u64 { + match case { + LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::One) => 0, + LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::Two) => 10177826, + LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::RegtestSapOnly) => 1, + LegacyWalletCase::ZingoV28 => 10342837, + LegacyWalletCase::OldWalletReorgTestWallet => 1, + } + } } diff --git a/zingolib/src/wallet/disk/testing/tests.rs b/zingolib/src/wallet/disk/testing/tests.rs index dd482a750..ec07e463b 100644 --- a/zingolib/src/wallet/disk/testing/tests.rs +++ b/zingolib/src/wallet/disk/testing/tests.rs @@ -116,11 +116,11 @@ async fn load_wallet_from_v26_dat_file() { // --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" // with 3 addresses containing all receivers. // including orchard and sapling transactions - let wallet = - LightWallet::load_example_wallet(LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::One)) - .await; + let case = LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::One); - loaded_wallet_assert(wallet, 0, 3).await; + let wallet = LightWallet::load_example_wallet(case.clone()).await; + + loaded_wallet_assert(wallet, LightWallet::example_expected_balance(case), 3).await; } #[ignore = "flakey test"] @@ -139,11 +139,11 @@ async fn load_wallet_from_v26_2_dat_file() { // --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" // with 3 addresses containing all receivers. // including orchard and sapling transactions - let wallet = - LightWallet::load_example_wallet(LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::Two)) - .await; + let case = LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::Two); + + let wallet = LightWallet::load_example_wallet(case.clone()).await; - loaded_wallet_assert(wallet, 10177826, 1).await; + loaded_wallet_assert(wallet, LightWallet::example_expected_balance(case), 1).await; } #[ignore = "flakey test"] @@ -152,9 +152,11 @@ async fn load_wallet_from_v28_dat_file() { // We test that the LightWallet can be read from v28 .dat file // --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" // with 3 addresses containing all receivers. - let wallet = LightWallet::load_example_wallet(LegacyWalletCase::ZingoV28).await; + let case = LegacyWalletCase::ZingoV28; + + let wallet = LightWallet::load_example_wallet(case.clone()).await; - loaded_wallet_assert(wallet, 10342837, 3).await; + loaded_wallet_assert(wallet, LightWallet::example_expected_balance(case), 3).await; } #[tokio::test] From 4d81b8df66388cb3d446ece1bbed0f51831830f7 Mon Sep 17 00:00:00 2001 From: fluidvanadium Date: Wed, 14 Aug 2024 21:55:18 +0000 Subject: [PATCH 03/13] updated parameter identifier --- zingolib/src/wallet/disk/testing/tests.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/zingolib/src/wallet/disk/testing/tests.rs b/zingolib/src/wallet/disk/testing/tests.rs index ec07e463b..2df9ddaef 100644 --- a/zingolib/src/wallet/disk/testing/tests.rs +++ b/zingolib/src/wallet/disk/testing/tests.rs @@ -9,7 +9,11 @@ use super::super::LightWallet; use super::examples::LegacyWalletCase; use super::examples::LegacyWalletCaseZingoV26; -async fn loaded_wallet_assert(wallet: LightWallet, expected_balance: u64, num_addresses: usize) { +async fn loaded_wallet_assert( + wallet: LightWallet, + expected_balance: u64, + expected_num_addresses: usize, +) { let expected_mnemonic = ( zcash_primitives::zip339::Mnemonic::from_phrase( crate::testvectors::seeds::CHIMNEY_BETTER_SEED.to_string(), @@ -60,7 +64,7 @@ async fn loaded_wallet_assert(wallet: LightWallet, expected_balance: u64, num_ad .unwrap() ); - assert_eq!(wc.addresses().len(), num_addresses); + assert_eq!(wc.addresses().len(), expected_num_addresses); for addr in wc.addresses().iter() { assert!(addr.orchard().is_some()); assert!(addr.sapling().is_some()); From e08c43c20e75f5dce892cea50e99da51c29894e5 Mon Sep 17 00:00:00 2001 From: fluidvanadium Date: Wed, 14 Aug 2024 22:03:35 +0000 Subject: [PATCH 04/13] example_expected_num_addresses --- zingolib/src/wallet/disk/testing/examples.rs | 15 ++++++++++++-- zingolib/src/wallet/disk/testing/tests.rs | 21 +++++++++++++++++--- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/zingolib/src/wallet/disk/testing/examples.rs b/zingolib/src/wallet/disk/testing/examples.rs index a1462ed6b..6c933a565 100644 --- a/zingolib/src/wallet/disk/testing/examples.rs +++ b/zingolib/src/wallet/disk/testing/examples.rs @@ -67,9 +67,20 @@ impl LightWallet { match case { LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::One) => 0, LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::Two) => 10177826, - LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::RegtestSapOnly) => 1, + LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::RegtestSapOnly) => todo!(), LegacyWalletCase::ZingoV28 => 10342837, - LegacyWalletCase::OldWalletReorgTestWallet => 1, + LegacyWalletCase::OldWalletReorgTestWallet => todo!(), + } + } + + /// each wallet file has a saved balance + pub fn example_expected_num_addresses(case: LegacyWalletCase) -> usize { + match case { + LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::One) => 3, + LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::Two) => 1, + LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::RegtestSapOnly) => todo!(), + LegacyWalletCase::ZingoV28 => 3, + LegacyWalletCase::OldWalletReorgTestWallet => todo!(), } } } diff --git a/zingolib/src/wallet/disk/testing/tests.rs b/zingolib/src/wallet/disk/testing/tests.rs index 2df9ddaef..0f2fc3c76 100644 --- a/zingolib/src/wallet/disk/testing/tests.rs +++ b/zingolib/src/wallet/disk/testing/tests.rs @@ -124,7 +124,12 @@ async fn load_wallet_from_v26_dat_file() { let wallet = LightWallet::load_example_wallet(case.clone()).await; - loaded_wallet_assert(wallet, LightWallet::example_expected_balance(case), 3).await; + loaded_wallet_assert( + wallet, + LightWallet::example_expected_balance(case.clone()), + LightWallet::example_expected_num_addresses(case), + ) + .await; } #[ignore = "flakey test"] @@ -147,7 +152,12 @@ async fn load_wallet_from_v26_2_dat_file() { let wallet = LightWallet::load_example_wallet(case.clone()).await; - loaded_wallet_assert(wallet, LightWallet::example_expected_balance(case), 1).await; + loaded_wallet_assert( + wallet, + LightWallet::example_expected_balance(case.clone()), + LightWallet::example_expected_num_addresses(case), + ) + .await; } #[ignore = "flakey test"] @@ -160,7 +170,12 @@ async fn load_wallet_from_v28_dat_file() { let wallet = LightWallet::load_example_wallet(case.clone()).await; - loaded_wallet_assert(wallet, LightWallet::example_expected_balance(case), 3).await; + loaded_wallet_assert( + wallet, + LightWallet::example_expected_balance(case.clone()), + LightWallet::example_expected_num_addresses(case), + ) + .await; } #[tokio::test] From f41d524ec8411ae88b2069849a9b2447e8c31c5e Mon Sep 17 00:00:00 2001 From: fluidvanadium Date: Wed, 14 Aug 2024 22:14:20 +0000 Subject: [PATCH 05/13] rehabilitated v26-2 test --- zingolib/src/wallet/disk/testing/examples.rs | 4 ++-- zingolib/src/wallet/disk/testing/tests.rs | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/zingolib/src/wallet/disk/testing/examples.rs b/zingolib/src/wallet/disk/testing/examples.rs index 6c933a565..7f5a5e8ac 100644 --- a/zingolib/src/wallet/disk/testing/examples.rs +++ b/zingolib/src/wallet/disk/testing/examples.rs @@ -66,7 +66,7 @@ impl LightWallet { pub fn example_expected_balance(case: LegacyWalletCase) -> u64 { match case { LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::One) => 0, - LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::Two) => 10177826, + LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::Two) => 0, LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::RegtestSapOnly) => todo!(), LegacyWalletCase::ZingoV28 => 10342837, LegacyWalletCase::OldWalletReorgTestWallet => todo!(), @@ -77,7 +77,7 @@ impl LightWallet { pub fn example_expected_num_addresses(case: LegacyWalletCase) -> usize { match case { LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::One) => 3, - LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::Two) => 1, + LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::Two) => 3, LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::RegtestSapOnly) => todo!(), LegacyWalletCase::ZingoV28 => 3, LegacyWalletCase::OldWalletReorgTestWallet => todo!(), diff --git a/zingolib/src/wallet/disk/testing/tests.rs b/zingolib/src/wallet/disk/testing/tests.rs index 0f2fc3c76..4569e8300 100644 --- a/zingolib/src/wallet/disk/testing/tests.rs +++ b/zingolib/src/wallet/disk/testing/tests.rs @@ -132,7 +132,6 @@ async fn load_wallet_from_v26_dat_file() { .await; } -#[ignore = "flakey test"] #[tokio::test] async fn load_wallet_from_v26_2_dat_file() { // We test that the LightWallet can be read from v26 .dat file @@ -160,7 +159,6 @@ async fn load_wallet_from_v26_2_dat_file() { .await; } -#[ignore = "flakey test"] #[tokio::test] async fn load_wallet_from_v28_dat_file() { // We test that the LightWallet can be read from v28 .dat file From 2aa05511450555ff5ab244722b4acc8cfd3c400a Mon Sep 17 00:00:00 2001 From: fluidvanadium Date: Thu, 15 Aug 2024 18:22:42 +0000 Subject: [PATCH 06/13] ExampleWalletNetworkCase --- zingolib/src/wallet/disk/testing/examples.rs | 27 ++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/zingolib/src/wallet/disk/testing/examples.rs b/zingolib/src/wallet/disk/testing/examples.rs index 7f5a5e8ac..d9db3ad89 100644 --- a/zingolib/src/wallet/disk/testing/examples.rs +++ b/zingolib/src/wallet/disk/testing/examples.rs @@ -1,5 +1,32 @@ use super::super::LightWallet; +/// as opposed to [LegacyWalletCase], which enumerates test cases compiled from the history of zingo wallt tests, this ExampleWalletNetworkCase is meant to fully organize the set of test cases. +#[non_exhaustive] +#[derive(Clone)] +pub enum ExampleWalletNetworkCase { + /// / + Mainnet(ExampleMainnetWalletSeedCase), + /// / + Testnet(ExampleTestnetWalletSeedCase), + /// / + Regtest(ExampleRegtestWalletSeedCase), + /// / + Legacy(LegacyWalletCase), +} + +/// / +#[non_exhaustive] +#[derive(Clone)] +pub enum ExampleMainnetWalletSeedCase {} +/// / +#[non_exhaustive] +#[derive(Clone)] +pub enum ExampleTestnetWalletSeedCase {} +/// / +#[non_exhaustive] +#[derive(Clone)] +pub enum ExampleRegtestWalletSeedCase {} + /// i do not know the difference between these wallets but i will find out soon /// what can these files do? #[non_exhaustive] From a9429ff0bb71378e797630bec4ed446948d5bfaa Mon Sep 17 00:00:00 2001 From: fluidvanadium Date: Thu, 15 Aug 2024 18:37:35 +0000 Subject: [PATCH 07/13] test showing the note has no index bug is live --- zingolib/src/wallet/disk/testing/examples.rs | 8 ++++---- .../zingo-wallet.dat} | Bin .../zingo-wallet.dat} | Bin 3 files changed, 4 insertions(+), 4 deletions(-) rename zingolib/src/wallet/disk/testing/examples/{zingo-wallet-v26.dat => v26-1/zingo-wallet.dat} (100%) rename zingolib/src/wallet/disk/testing/examples/{zingo-wallet-v26-2.dat => v26-2/zingo-wallet.dat} (100%) diff --git a/zingolib/src/wallet/disk/testing/examples.rs b/zingolib/src/wallet/disk/testing/examples.rs index d9db3ad89..109e9b1e2 100644 --- a/zingolib/src/wallet/disk/testing/examples.rs +++ b/zingolib/src/wallet/disk/testing/examples.rs @@ -58,13 +58,13 @@ impl LightWallet { match case { LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::One) => { LightWallet::unsafe_from_buffer_testnet(include_bytes!( - "examples/zingo-wallet-v26.dat" + "examples/v26-1/zingo-wallet.dat" )) .await } LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::Two) => { LightWallet::unsafe_from_buffer_testnet(include_bytes!( - "examples/zingo-wallet-v26.dat" + "examples/v26-2/zingo-wallet.dat" )) .await } @@ -93,7 +93,7 @@ impl LightWallet { pub fn example_expected_balance(case: LegacyWalletCase) -> u64 { match case { LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::One) => 0, - LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::Two) => 0, + LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::Two) => 10177826, LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::RegtestSapOnly) => todo!(), LegacyWalletCase::ZingoV28 => 10342837, LegacyWalletCase::OldWalletReorgTestWallet => todo!(), @@ -104,7 +104,7 @@ impl LightWallet { pub fn example_expected_num_addresses(case: LegacyWalletCase) -> usize { match case { LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::One) => 3, - LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::Two) => 3, + LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::Two) => 1, LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::RegtestSapOnly) => todo!(), LegacyWalletCase::ZingoV28 => 3, LegacyWalletCase::OldWalletReorgTestWallet => todo!(), diff --git a/zingolib/src/wallet/disk/testing/examples/zingo-wallet-v26.dat b/zingolib/src/wallet/disk/testing/examples/v26-1/zingo-wallet.dat similarity index 100% rename from zingolib/src/wallet/disk/testing/examples/zingo-wallet-v26.dat rename to zingolib/src/wallet/disk/testing/examples/v26-1/zingo-wallet.dat diff --git a/zingolib/src/wallet/disk/testing/examples/zingo-wallet-v26-2.dat b/zingolib/src/wallet/disk/testing/examples/v26-2/zingo-wallet.dat similarity index 100% rename from zingolib/src/wallet/disk/testing/examples/zingo-wallet-v26-2.dat rename to zingolib/src/wallet/disk/testing/examples/v26-2/zingo-wallet.dat From ab72a38bda646544b55bd61aab90b30f4ea1099b Mon Sep 17 00:00:00 2001 From: fluidvanadium Date: Thu, 15 Aug 2024 18:40:23 +0000 Subject: [PATCH 08/13] ignored failing tests because thats how CI rolls --- zingolib/src/wallet/disk/testing/tests.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/zingolib/src/wallet/disk/testing/tests.rs b/zingolib/src/wallet/disk/testing/tests.rs index 4569e8300..09a508566 100644 --- a/zingolib/src/wallet/disk/testing/tests.rs +++ b/zingolib/src/wallet/disk/testing/tests.rs @@ -132,6 +132,7 @@ async fn load_wallet_from_v26_dat_file() { .await; } +#[ignore = "test proves note has no index bug is a breaker"] #[tokio::test] async fn load_wallet_from_v26_2_dat_file() { // We test that the LightWallet can be read from v26 .dat file @@ -159,6 +160,7 @@ async fn load_wallet_from_v26_2_dat_file() { .await; } +#[ignore = "test fails because ZFZ panics in regtest"] #[tokio::test] async fn load_wallet_from_v28_dat_file() { // We test that the LightWallet can be read from v28 .dat file From 7a963e973a83fc8d385a76990e9d02ae08119df3 Mon Sep 17 00:00:00 2001 From: fluidvanadium Date: Mon, 19 Aug 2024 15:05:34 +0000 Subject: [PATCH 09/13] this commit comes after a rebasis where i eliminated a commit messing with legacy wallet tests. i still intend to replace that function, but first i will fill out the replacement --- zingolib/src/wallet/disk/testing/examples.rs | 24 ++++++++++++++++++-- zingolib/src/wallet/disk/testing/tests.rs | 10 ++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/zingolib/src/wallet/disk/testing/examples.rs b/zingolib/src/wallet/disk/testing/examples.rs index 109e9b1e2..4437a748c 100644 --- a/zingolib/src/wallet/disk/testing/examples.rs +++ b/zingolib/src/wallet/disk/testing/examples.rs @@ -17,11 +17,31 @@ pub enum ExampleWalletNetworkCase { /// / #[non_exhaustive] #[derive(Clone)] -pub enum ExampleMainnetWalletSeedCase {} +pub enum ExampleMainnetWalletSeedCase { + /// this is a mainnet seed + VTFCORFBCBPCTCFUPMEGMWBP(ExampleVTFCORFBCBPCTCFUPMEGMWBPWalletVersionCase), +} +/// / +#[non_exhaustive] +#[derive(Clone)] +pub enum ExampleVTFCORFBCBPCTCFUPMEGMWBPWalletVersionCase { + /// wallet was last saved in this serialization version + V28, +} /// / #[non_exhaustive] #[derive(Clone)] -pub enum ExampleTestnetWalletSeedCase {} +pub enum ExampleTestnetWalletSeedCase { + /// This is a testnet seed. + MSKMGDBHOTBPETCJWCSPGOPP(ExampleMSKMGDBHOTBPETCJWCSPGOPPWalletCommitCase), +} +/// / +#[non_exhaustive] +#[derive(Clone)] +pub enum ExampleMSKMGDBHOTBPETCJWCSPGOPPWalletCommitCase { + /// wallet was last saved by the code in this commit + Gab72a38b, +} /// / #[non_exhaustive] #[derive(Clone)] diff --git a/zingolib/src/wallet/disk/testing/tests.rs b/zingolib/src/wallet/disk/testing/tests.rs index 09a508566..ac2f6b396 100644 --- a/zingolib/src/wallet/disk/testing/tests.rs +++ b/zingolib/src/wallet/disk/testing/tests.rs @@ -6,9 +6,19 @@ use crate::lightclient::LightClient; use super::super::LightWallet; +use super::examples::ExampleMainnetWalletSeedCase; use super::examples::LegacyWalletCase; use super::examples::LegacyWalletCaseZingoV26; +#[tokio::test] +async fn verify_example_wallet_mainnet_vtfcorfbcbpctcfupmegmwbp_v28() { + // let wallet = + // LightWallet::load_example_wallet(super::examples::ExampleWalletNetworkCase::Mainnet( + // ExampleMainnetWalletSeedCase::VTFCORFBCBPCTCFUPMEGMWBP, + // )) + // .await; +} + async fn loaded_wallet_assert( wallet: LightWallet, expected_balance: u64, From e4d66ec4add2497a4f36040bdfaa3e4fb6669ed1 Mon Sep 17 00:00:00 2001 From: fluidvanadium Date: Mon, 19 Aug 2024 15:06:13 +0000 Subject: [PATCH 10/13] renamed old wallet loader tree to ..._legacy --- libtonode-tests/tests/wallet.rs | 2 +- zingolib/src/wallet/disk/testing/examples.rs | 2 +- zingolib/src/wallet/disk/testing/tests.rs | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libtonode-tests/tests/wallet.rs b/libtonode-tests/tests/wallet.rs index f88ee4762..ea6a1eab0 100644 --- a/libtonode-tests/tests/wallet.rs +++ b/libtonode-tests/tests/wallet.rs @@ -73,7 +73,7 @@ mod load_wallet { let _cph = regtest_manager.launch(false).unwrap(); println!("loading wallet"); - let wallet = LightWallet::load_example_wallet( + let wallet = LightWallet::load_example_wallet_legacy( zingolib::wallet::disk::testing::examples::LegacyWalletCase::OldWalletReorgTestWallet, ) .await; diff --git a/zingolib/src/wallet/disk/testing/examples.rs b/zingolib/src/wallet/disk/testing/examples.rs index 4437a748c..bf9de24ae 100644 --- a/zingolib/src/wallet/disk/testing/examples.rs +++ b/zingolib/src/wallet/disk/testing/examples.rs @@ -74,7 +74,7 @@ pub enum LegacyWalletCase { /// loads test wallets impl LightWallet { /// loads any one of the test wallets included in the examples - pub async fn load_example_wallet(case: LegacyWalletCase) -> Self { + pub async fn load_example_wallet_legacy(case: LegacyWalletCase) -> Self { match case { LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::One) => { LightWallet::unsafe_from_buffer_testnet(include_bytes!( diff --git a/zingolib/src/wallet/disk/testing/tests.rs b/zingolib/src/wallet/disk/testing/tests.rs index ac2f6b396..2539f74ce 100644 --- a/zingolib/src/wallet/disk/testing/tests.rs +++ b/zingolib/src/wallet/disk/testing/tests.rs @@ -109,7 +109,7 @@ async fn loaded_wallet_assert( #[tokio::test] async fn load_and_parse_different_wallet_versions() { - let _loaded_wallet = LightWallet::load_example_wallet(LegacyWalletCase::ZingoV26( + let _loaded_wallet = LightWallet::load_example_wallet_legacy(LegacyWalletCase::ZingoV26( LegacyWalletCaseZingoV26::RegtestSapOnly, )) .await; @@ -132,7 +132,7 @@ async fn load_wallet_from_v26_dat_file() { // including orchard and sapling transactions let case = LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::One); - let wallet = LightWallet::load_example_wallet(case.clone()).await; + let wallet = LightWallet::load_example_wallet_legacy(case.clone()).await; loaded_wallet_assert( wallet, @@ -160,7 +160,7 @@ async fn load_wallet_from_v26_2_dat_file() { // including orchard and sapling transactions let case = LegacyWalletCase::ZingoV26(LegacyWalletCaseZingoV26::Two); - let wallet = LightWallet::load_example_wallet(case.clone()).await; + let wallet = LightWallet::load_example_wallet_legacy(case.clone()).await; loaded_wallet_assert( wallet, @@ -178,7 +178,7 @@ async fn load_wallet_from_v28_dat_file() { // with 3 addresses containing all receivers. let case = LegacyWalletCase::ZingoV28; - let wallet = LightWallet::load_example_wallet(case.clone()).await; + let wallet = LightWallet::load_example_wallet_legacy(case.clone()).await; loaded_wallet_assert( wallet, @@ -204,7 +204,7 @@ async fn reload_wallet_from_buffer() { // --birthday 0 // --nosync // with 3 addresses containing all receivers. - let mid_wallet = LightWallet::load_example_wallet(LegacyWalletCase::ZingoV28).await; + let mid_wallet = LightWallet::load_example_wallet_legacy(LegacyWalletCase::ZingoV28).await; let mid_client = LightClient::create_from_wallet_async(mid_wallet) .await From ae28599eb0d307a9c40442387acf28d7df13175b Mon Sep 17 00:00:00 2001 From: fluidvanadium Date: Mon, 19 Aug 2024 15:37:48 +0000 Subject: [PATCH 11/13] set up basic organized wallet verification --- zingolib/src/wallet/disk/testing/examples.rs | 36 +++++++++++++++++--- zingolib/src/wallet/disk/testing/tests.rs | 22 +++++++++--- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/zingolib/src/wallet/disk/testing/examples.rs b/zingolib/src/wallet/disk/testing/examples.rs index bf9de24ae..617b0973b 100644 --- a/zingolib/src/wallet/disk/testing/examples.rs +++ b/zingolib/src/wallet/disk/testing/examples.rs @@ -10,8 +10,6 @@ pub enum ExampleWalletNetworkCase { Testnet(ExampleTestnetWalletSeedCase), /// / Regtest(ExampleRegtestWalletSeedCase), - /// / - Legacy(LegacyWalletCase), } /// / @@ -33,12 +31,12 @@ pub enum ExampleVTFCORFBCBPCTCFUPMEGMWBPWalletVersionCase { #[derive(Clone)] pub enum ExampleTestnetWalletSeedCase { /// This is a testnet seed. - MSKMGDBHOTBPETCJWCSPGOPP(ExampleMSKMGDBHOTBPETCJWCSPGOPPWalletCommitCase), + MSKMGDBHOTBPETCJWCSPGOPP(ExampleMSKMGDBHOTBPETCJWCSPGOPPWalletVersionCase), } /// / #[non_exhaustive] #[derive(Clone)] -pub enum ExampleMSKMGDBHOTBPETCJWCSPGOPPWalletCommitCase { +pub enum ExampleMSKMGDBHOTBPETCJWCSPGOPPWalletVersionCase { /// wallet was last saved by the code in this commit Gab72a38b, } @@ -47,6 +45,36 @@ pub enum ExampleMSKMGDBHOTBPETCJWCSPGOPPWalletCommitCase { #[derive(Clone)] pub enum ExampleRegtestWalletSeedCase {} +/// loads test wallets +impl LightWallet { + /// loads any one of the test wallets included in the examples + pub async fn load_example_wallet(case: ExampleWalletNetworkCase) -> Self { + match case { + ExampleWalletNetworkCase::Mainnet( + ExampleMainnetWalletSeedCase::VTFCORFBCBPCTCFUPMEGMWBP( + ExampleVTFCORFBCBPCTCFUPMEGMWBPWalletVersionCase::V28, + ), + ) => { + LightWallet::unsafe_from_buffer_regtest(include_bytes!( + "examples/mainnet/vtfcorfbcbpctcfupmegmwbp/v28/zingo-wallet.dat" + )) + .await + } + ExampleWalletNetworkCase::Testnet( + ExampleTestnetWalletSeedCase::MSKMGDBHOTBPETCJWCSPGOPP( + ExampleMSKMGDBHOTBPETCJWCSPGOPPWalletVersionCase::Gab72a38b, + ), + ) => { + LightWallet::unsafe_from_buffer_regtest(include_bytes!( + "examples/testnet/mskmgdbhotbpetcjwcspgopp/Gab72a38b/zingo-wallet.dat" + )) + .await + } + _ => unimplemented!(), + } + } +} + /// i do not know the difference between these wallets but i will find out soon /// what can these files do? #[non_exhaustive] diff --git a/zingolib/src/wallet/disk/testing/tests.rs b/zingolib/src/wallet/disk/testing/tests.rs index 2539f74ce..d01d1076a 100644 --- a/zingolib/src/wallet/disk/testing/tests.rs +++ b/zingolib/src/wallet/disk/testing/tests.rs @@ -12,11 +12,23 @@ use super::examples::LegacyWalletCaseZingoV26; #[tokio::test] async fn verify_example_wallet_mainnet_vtfcorfbcbpctcfupmegmwbp_v28() { - // let wallet = - // LightWallet::load_example_wallet(super::examples::ExampleWalletNetworkCase::Mainnet( - // ExampleMainnetWalletSeedCase::VTFCORFBCBPCTCFUPMEGMWBP, - // )) - // .await; + let wallet = + LightWallet::load_example_wallet(super::examples::ExampleWalletNetworkCase::Mainnet( + ExampleMainnetWalletSeedCase::VTFCORFBCBPCTCFUPMEGMWBP( + super::examples::ExampleVTFCORFBCBPCTCFUPMEGMWBPWalletVersionCase::V28, + ), + )) + .await; +} +#[tokio::test] +async fn verify_example_wallet_mainnet_mskmgdbhotbpetcjwcspgopp_gab72a38b() { + let wallet = + LightWallet::load_example_wallet(super::examples::ExampleWalletNetworkCase::Testnet( + super::examples::ExampleTestnetWalletSeedCase::MSKMGDBHOTBPETCJWCSPGOPP( + super::examples::ExampleMSKMGDBHOTBPETCJWCSPGOPPWalletVersionCase::Gab72a38b, + ), + )) + .await; } async fn loaded_wallet_assert( From 252a7d61337a49595da1034bf05667d6764b8de8 Mon Sep 17 00:00:00 2001 From: fluidvanadium Date: Mon, 19 Aug 2024 15:44:28 +0000 Subject: [PATCH 12/13] verify tests run! --- .../v28}/zingo-wallet.dat | Bin .../Gab72a38b/zingo-wallet.dat | Bin 0 -> 69402 bytes 2 files changed, 0 insertions(+), 0 deletions(-) rename zingolib/src/wallet/disk/testing/examples/{missing_data_test => mainnet/vtfcorfbcbpctcfupmegmwbp/v28}/zingo-wallet.dat (100%) create mode 100644 zingolib/src/wallet/disk/testing/examples/testnet/mskmgdbhotbpetcjwcspgopp/Gab72a38b/zingo-wallet.dat diff --git a/zingolib/src/wallet/disk/testing/examples/missing_data_test/zingo-wallet.dat b/zingolib/src/wallet/disk/testing/examples/mainnet/vtfcorfbcbpctcfupmegmwbp/v28/zingo-wallet.dat similarity index 100% rename from zingolib/src/wallet/disk/testing/examples/missing_data_test/zingo-wallet.dat rename to zingolib/src/wallet/disk/testing/examples/mainnet/vtfcorfbcbpctcfupmegmwbp/v28/zingo-wallet.dat diff --git a/zingolib/src/wallet/disk/testing/examples/testnet/mskmgdbhotbpetcjwcspgopp/Gab72a38b/zingo-wallet.dat b/zingolib/src/wallet/disk/testing/examples/testnet/mskmgdbhotbpetcjwcspgopp/Gab72a38b/zingo-wallet.dat new file mode 100644 index 0000000000000000000000000000000000000000..15bb72c4d3cb2aaa4e1a61a3e09396e53e24dd90 GIT binary patch literal 69402 zcmaf*WmHwq*T?AwFChpBTrS-y0+LFnAP7iHhkyb~NOuSV(v6fzcS=g9q;z+OG(PuS zW&QmxmM```XZB}*XJ*fwnR_4M&p#wYByxm^o_F?CRVGKgeLNCb2u)8?-}9*A zyzNu0kEd>VJA;UX92-^r0c!8rIvJjtfEpOu&yV#$GUhJU1-GCW4zFstteMsM#olSw z5D%*%qrIy~Qnz;gsvqT@FO3gH7?Ed1c4Inthm)+aW(P8z>2jtGehXriy(afG(T{y~ zUr6eP!KBPTc%W|M9MBrhJjYT&VXo4RRF%SvBDhoPvITW4(FI%bf z{q&tCSzogh@yTW~6V%&j=5zXMK_FP*Rl1a+M9nhBZt9NH+7e-=yQTBA!VW(_Eo)&} zCO*!3X$#YT9yrwau|%uOD&<;Eo2$(B!=$BSzDoQXtNiC>3h#~8T zMYBvI;bd0}Dj*#M#=u)TC%zHg@)44g2(&V6b{_P()uH4%tB@MTb;0zCyS#tLedYOj9G z+DQ{AfZ#+_=Ecx!t4cL{z=ppG=l6itgO+s<8u!Z1`8OvnC66OME}TVutx4&>#uS0l zX}_g&1Em8mkpIxRfzg5I0s(6^*5{jJP2r<(ePhta!VpKHI-6B5<-Y(}{9a23tseBn|Zd3j|zd(X}hI!4W$DwkpIxRhS7oN0s&_r zrv2nv3*8Je7_Ph*F^WD?eTlJPM0rv>t@Ve_z&~`_d}AzL1}&S`jCuDyck9?rGFI+I zm|_UbZ~>NSXHClKo^A1G}7`c4Hzz5+_G zQ5->wC|N!wQ8#s&H_yOmoN3g|8h5VcHCBLN0XE2uKFrRfVvqwA8z;G$LyAkQ`3J%w z?4&L&cN)}Agbbl{T5joFLFvE?^ zhsVqAUUFK39=%tP*u^X=d!DwmOMGqR2=6Ioq!eC7>)h5G8TPZRAH zz)-fO=hJxRF4cTQK=m?zy@TL*yj?s`v}b>2ZQE<*N=m@y%3F2=X{+nQL38!befP$Y zow#FSr2;YkfDZNdt#942fhh-x06a;(<^g)Rg86)J5max{3CUXw-zogg>A;jgphEa{ zPZwxXK=vF+?CVC-bMY+%NSNX;B}8H<>Hwl7YTQI^$5Rv zBD}^MwvS@fFGJhUsxayGWroS4%ATXo*N$E`%LH|bo6^*KU+s9`7D0Pqh)|8X=E2$y7;{jm`6sAmCUzzt#?R1!ltD*&zxugKLyC#- zM)=1&!jmf*s_ZLr*Egprsh?Z$!jMZI08Jvo^C0o3=^6am-9!@0E;l`pI_uR+X6ZQd z_8X=fx?BnHx+b()A1N)Rck0+V=`mlE<<@6Cjlk~+jVra*bz+nAo&YwkZA48Q>Mq)K zapo45c7kQ;hpoCdRdo)ZTRufuI(D%OmLp=I5`a(d>wGI)ZI;I&yHZ?3xL=@QHTTr> z3xY-0&IG?|CW$K0q=%6mXu>b_jCSMuDnqj%t6~q>Y8CW4iG;#DTvEg0EC8FO;nTqA z`goH^1BRu!;Zvq{{kw0cq;u@{8@;g3z+!fIYGdE zZZyroK0X2UUVBV#&%g2d9~bQgng8yqK*9{$5= zz{X=xocijK*E9Z%pH)23@eQ~Ly~^}*e$lkmjVFo;s1yJnk&&R_qRx^ownws7$s-no z-F&N7*vT6Yzp8(&SLiw?0Bi>Nw!>(p6_Ns7=f9GoU}Dc?=s1&46>ei{a(^Bu=aKn4 zrX85Yaed*&g%WmCQQ`VsS<7s!URV8?(lULsDtVg*RL(^J*o7Qt^TH*2kH?1wGpmSJS z;W9UoVN;dEMN)OKK;6j9^$Px>XtvG9>!tFU3~R<2t*NUf zpB8z5p|P1A2)SLEdb68Tl(v?zYOQb7$*4WB2LX*DLwM*AXwr0`I;dlzDh)AH8zJUV z^@BkMcPc)1O{S+@!N@O($9@2>E7E_Kn6OvhL=(opIAsc#}{kBE>o?yyC4D&-ZGc6$@$}tteMI>O{>&t%JCI-lhQ^JF$ka;;ma?Pg3sFJVVM(W8;=4a4QoTSijuL@mYSV#oIfA z?zOXY#hvqF2f=0M-x}3RrX)YzZ-nrcM4wc1mI#gVZa9b(p1cp{h72ZX9tKKSw=7Fi z)|{a+Cy}f1%Gg%nExh+n2qUkeW)L@lHBWh;(}BG#c~XU9@SEkmrF+7YO{f{E$PW9pY2Ue7@ z53`BHfku*X&BEjz*asBvRkhADd;IDlyp;jLC63lad@t0j$fD(i`uuXPQ9pr8`|uQ& zn;4~b3G4I49jad>tE2~&P9E)e99%KcA^aVsD`sp*2?QWoM0Fu@daV1UoQmXzV$Ta` zwbgOUpB30419@NIjQfuAm@kERk-9u)xsS!|^tfN$j73|0@NQ-|mf9O2r@a>JY*=qe z&szf|%Ou%#Y`gGpddNS%TT12^3;VL7jt$s6xaJl4!Rt40yk#R=pb~i)$&ZDKPCSbv zDUI=9>eH$g(1Xwkz&xvK^|G%-PN(dIv3&&2b^1w`t=m1(-ixX~tIn4pcLJIea$R~Q zeUR+kPba%HScYf7K&NQWL2_m)am|vg$zg7c47R3zDk?XJO!w6qpz_aUL-l;0yfy0MKdei zeR<7d%ltVs8`E6aLVFYp8Sjigb`zO>hz`?EF7pM;}%6#n#;&wk|25Cqk zTy%-puqtwtly(^mVggMnImT61qa!!7=h5b*M4Vi zT@j&g@XGAQ_;$7s6y6C>{w~$MYO0C3t%1P^hy;rOylY%(k(Kg2?+VS?_**;@hP7Uz zk7lO1Uul;dc=T|x0ca93(??C5BBusigU3z>%)T+vo#d8MVPA1ROc;OuwL0Ddysr9_ zf`f5ejAnlG-HxO!eKr05Lp%_^bC&p0L^J2=h#_F};Qe{0>VlxsH6l(p)ugwxTvQ zDu+tUqlnI2%NlelrT&@9SHAvT07L71$940AyeQuS(bSM51Hz4vkYi~~?qIWy2GJ?} z_P`NX(HPg^Lr&FNtyt=GZ+nZ5c$qxYnGw6UP~IIea`-sK!2*a~c}r;P#N;{&{k|qz z{A1GEUB0@)iLjH<`72_*hn=blfDJnc%zL)Zx?B4s*Q>kZp}H+Tk>OW@=QTXLhV6;b z;`D#VbF|3e?2&Vp>axZ5yeEEL=bzGay6UhIW&OgoUs=%Vs@>~rE_+v| zOBS#xDh^0JVm1B-souRKRL%9v24>VB>dO<5+8vTEpV*C{k*@Yw#7 zvR%+AEMf3mAmGKW?D%#X>1UQpNUBvD-^t&awcIQ?Yx@wC*#Ajb!EM5zwb$-!z4)XG z*&%hOWBAs!->Yj8C;vvinJ{Jh`~}3A6<84y^vu^1b??xKVD@O!EcOkExf~(G*65jz zCC>eOf#cKNK;$tWXFH$pM0B+47!X=JxNr7)Pm)Dlr)lbO5FknE$tVFf$wJ0y*n0-~ zkH(b8y`u}_{4TZP1iV=T*@Rr3inl+jLg}R4()k6Y122&O(D?xvMXp>1~kNTQ_u-Gw1ROXQwsW!AApj8$iJwz z%PO+_>6`OMk#q#0V3le`}$YJ=ti0q~eCE(;U z;R3x{;bCmc!B(f&IybTJQoP~<7=7cPwDh-c!JP1$h87v#q=nX z+PzPbZbZ8N(7F2Zzum60=Qw^yo3v0YO+%NXrc>cB(kP4S|@5&)Wub2? z5@m*xpKx$S7%J-(SqGZUt1jWKrI3zJ1KLTrrE>(O122&O&^dz9f#(7N>mz|yMi`kA z1?5Rzxb%N~O3tZ`a)%;!UFencAMLc=(t%DC0;kDy5xT`9d79-si82leyt(hdmEAd? zGRm~dI%fDU0XkW~Sr}xptPCeuej8IR{iYi^rdt;fu<9(5N7flWNs}Pz zGksbkU;w2PcT49GN(Wvb|DkgTqXW+c0_Mx}>2sF=ZD-gIj7%$IVt<%v?L0?Z!b~|R z|3fF`mJW1OUZpRelw$G=r6V?y4WM=_YVDN0o+%mL`7*Kd39*)6_#|R?H+iY9Ns&`B% z?4sk>g%MO<=jMI=IK^g1p=_431$VnbqJzhpt5L`-LLxDfLq`KjC+3#U0hA8BK>nd~ z4J|VcV0_>?LHF6~r&_znlfFpS8H-E!(V5=4qde9zqcWje>;9EQ0MxhC9GlCBPs(;d`>=$;bAf=*b#e|rO*}{PBZ{`Um zj_dm$L4V5q-&8>)FJmu?UMog@hrJC{Vgz1QS7L4{X!bymoj(R?^SCz|lBhFnAd zmreP8{$|vB_XCM$OD1GaCI|ZrZyB1V1NV+Cb@iyrr`Tr2{XJ z|Ipck(Shdz0lP^jTMlz!Qe`*BEw-3wHwqQbhMR_d+qO?4|0Cy*w{)NzgdDye(Z;`i z%YpfR#MsY1G1Q?=ZURe-d9B7s&e&aXI0AHBn)|4XR#d#XBS2Xo(lwQDK&F^5Fj7V z8|j#qp^5GqX>zDRq*RXh1bgO>b`G=ux28Z``A{X(_@*$zB(DzpT*}F=gyrJv#n+q9 zOz!0ywa)1P9USo)oQvz93C|txYCqDsBjB@JZs19mgZiC6F)cGrCKiaC20iQ{p1D$( z0Gh;(TUub=L+RHf{Nl3(9#MD*Ge<!7mxs zIsa&9@|F&Csz6LW7kD*ILRW(C8$(A=h5f-{4Ck@4#*A{@r?utJ6L$eRc4lr1;dfiE zOPC^3hhoG(Xa~yQ`|@K=jl@L}NmchTCJ;G=4Jl{5hoUW}b7S_`RCALhUf!ZPgmAAs z>d%?`koGpRsv%x{>{v7HJ9{RgQ6sHkf0#YJlZNLWE@`p?RS^N^p zXEaf-8~WCqg3qz?^4~#bk1OK^RK+-;bOLYbY(eS33*;X<*UykZTQENGoFHHm|M82y z823N_gf%5h~O0x(&h zjRro|=f>XleO+dz>tmmBRWkyj=1!CH_gP|k%4lR@{?75%dkMIWBl{aG;i%krge#pK z=^+d_ZJ%iq7dD;*L3n>JzPd*+n{iNjNS2kwTZ6J&aI*6A^tDMLHN&FShWNz&O|J2i??kD>PG>KtuL|P~ zxyv+5ix9&}uALg`pL0War$cEqqVo2YEl@s)03MdVrt4OYe%KGr{IEJ*?fj!66TLSp{6O2_=4V_YxAQ^RG z`bU5W<+K}E3muWP?4RO9nd7s$o%Pg^#f{mice*qzN&T+$2Lv{8Qhx6-hLkL=oAWfo zGh*#F305pI=6HMg*MxiCnE^V0jRbS_!pqI>MI!>)XTk{CzdO5Xa6Xpukyd&;JK5b! zv4@J#|5k*XP!YmY%ReIA1#QA42+suqE_jnwTi}i>WF&9-kY`F+aS+rd5vqx(ok0C} zc%RGsUuj@^!?qdkE1;r=ub#+OZjq%H>{H9Zsk#q(PcA*R1nP z@N@p)u7z8PU;u5#Ib;1A*-;aupZlf_-V7}6Ym4=f(Kpu;h8Vu9%HuR z&4;J}HlDPKWL32IgwIW_vwxP;(bE|kXHYuikf56xLcX8P<3j290(2^&`!gF*I`9Jd z51kDd9e6GfaGsVTNWe|^ik{A5r&^)qs9ia7N4Ayd zSnQI5agk9V@_Iho_49|y4u*{fYYAf?o`PVBu=J|vU>eB%2mA66_65cyGx-@^witwyDR zofA(|UAP)OC(f?ix}r0r>N_c#sGb2fa-qLFKl)%1BQaNqIc{Gc9B@ValoTn!UM8{F zHslIbfzt83rLzX5122&O&{>1gf#(7Nvu!Klffk%J9J7khvP9U&_xJfb3vx`prM_YO zGq^9_(t!@{R%ty*+HV(l<@vg8E}3nIcA9IHw3ZDlb|)I=rPSH_0Xp*%>3tv1-Iwcp ztkgHP(At*@ZC?!LG4I^3*o@pH>stUK$7$AkzZfrH6V!}mpBOVi^@|~H_Uck&hNFH% z0PI|04A?Lov~B1xn}2;4M}E&sv4jffvYs z=&Zu%z;l6s9a3j0o3e2HQeUeU#c7=sgkdhletLkM=2DOOhfd2a9cbY+p0zXUvyWiI zG>DV_+fX_qqU z(C<@T3&Iv`9?d9wL%0YMoF6r!Fua5BnT{i~lpBaP{$w>ZJ6PRE1L*9t^AQh_UnaXo zG-%$$Ye&3DA4>}>5vj%r6vlWPg3w-+zc*-&9>!oW?NnoF@4c<0=@Yqlh zb3YK8=X=aGo={nK^I3f9+IL!v6C}oO4e-HZdOp_iTeVo9etf&Aj9Nu0>|KIuJL%W< zb;pNHqRmo&C(=SL6tH{H^~w_pR76GxPV?rVBdMIZL3bH<5gP6zP6VJy%h`pbVa>?s z1%(U5AHTj8n{8lAbj{p9(&DBHMV-040ABazQ;>4Imk&8dCewF!Yhn_&dk*Y&$4Dx_`F7(F0qdlT+mtOsQwERi zKPlSqf0Dg68TWH9uPpg-Lv4BFjYCcGNf z`9|L29?q(3`AZ#3R}?%lBt6uNn_l?zQpD;RK!+!xI{m@j00x@R=|gqwsIjYFijFL^ zk}HnCU%oM}Rv#D7>*gbIi0fD$k!sL|=Y&-UInVN)k zT4+&OjaHgRKKeK1JZ&jI)wv9Pg;Ls{v%?2aI=^n|EJ5kO3*;X<*F;F5B^V!gP7p9@ z*L>3pN%ci%k@w8RWnA*)S0hHbCpYoY&+GmO+UJ%Jw8LBR9#eiG>MG?YH6JN&!Wq?B zrGWg{NlNjJZ*;d8D~kpAoFF~K@urYcMWQur1zQQX)+nIJugTu)=}MJJ(2wNg1JrYK z=*lxFDovSF?}xZ3ksF;3Dh#ZCT)o&3G?LBf%*YJb97@($&DbQ+E|4<`2c$-FdI+JG zWU`nA%5~rvkzC8*0fL66Y(`KS{GF>OB``SiN3cG2ouU0+WjZs80kc6r&-M@-4$vfs z?qlCx@*i&9Qus(*XX8(dcR2KanpQctuKu*ajlg-R$JQo26K@z6YDd8u7_pyRj zxlNs|-^I&yZ6Etu5G74L=d^R0^&Zcjk^4xF<(LdKX?!jI6a8kVnhC}B8ck+IBpPMb zYi5CDGw%w^qAKzqt3Z?L71lmG>(y!DDLQYxov1*XObs-8851%WGqCAV>((j;*gWY- zX_)a$iC>PjnX!0AYQuFWmDcyoWW;p^=VWzj+DoX4j&D`82vrfhbpNBGUC<&-L-1T6 z;1=omL;vBPAl5jl(Wj3>D&FT%TqD-tc3HN5`_spMr2cO&;w8QRRbhcM3+v?4&*QH` z(~9=;4b`C6;h!nqdQR3=PD-X+{?$a}A5viP!Bu`k&hX=Lq0;OKvx;Cp2=+n9pyAT{N^)yIi+)Odz&B%( zEg~6tG-`Chps|%;j%frPN@w?$&H|JUyg>e;156qVFh1~{AYj#{U4^653tA7AtfYc; zKUdVY*3}gsqGB{o)<1mGZ}~v`SZ^Qnuv)t-i5@Yc*~00%!xc5PlI|zsxGzs=G_yrR zCjma?lEL&L7~qFaF+Q?K7GkIc+pAVWyN+0+@$-l3`UbGiiP;YcXqq!U%wA^o;!hwO zeXwUZtuXxb=|b-JgY4>-R9HWh7hPBJtn%$ifG=Yt3m2^0 z2cXvEOsuNf;O-14sHX?$u`k(BU}_G19Cqs1s5Zwig{Ex#Hf8hBl)+>B|57#&OBp;T z2sqQBwu>v`(H!>5IKOK5_xqBZez*3A<3OJX{l>YF^1pdrg`&mn^)Bsh29_GX z!lh!VfD`RUH~Cl7E?RhR4`Pev4&{4V_=FasgtQI(aO|TD*_yks zc?ZxW9gVv^OJQMeMMQUyTTtJoJ3U@+A-h(&@FedSN7eoSTl939uV`O;c=6r)*;M`j z`oUWMZlLDEy&2gzyoQnV?3q+RPn0g$$jJUd6V2^?g`QL3+R54y@Xj{XggN>R$bBPO z3`p7fZOZ1LDTBxMpOo!_=3ohf=K=x0Nl*y=#4(W9A!W6JB7r#O!h@liJKt?FglqgK zVfD8OgDwdbZo*itHY<@X^i=XLx*`T2^K^rcW3cZQo(R}66?W4AbXt~Zidb|g5X=($ zEIDtUP?i$}eR`ke&36AgyUL`=$TAT58Y;QN#IxSJi&S^P)ss9yGc`%ijDXPS-zz+3#9`ukpIw` zh0%fM0s(s&{HRR`-CQP*LdTMs_L&_}j8n)=tZL1gLijTR?IrzB&aE+@y_~Pg=MiRv z1U>NhA8NgmZXfNj+g|fGH8x`ugK5XQD=8(#l!@?EmpO}(j*+jvn(VGm+*_YT=@gaS z7YrEy9VCb)b(bf}H{&<@@g2LFQ{_A?8ORdy+iFxc?&v$HFzu|EU*w-j$}R|`aK)MC zq4$TBjN#-B_}54Hj9_GlJivz1S-hn)1Em8mkbmd^BlHZ64?HIbc+2dP@x3-a*11%NI%A;#~-o~ zE^%_n0o@%cXc-i0Q0V)6mto3UMHYiEy~JOQbqp(tA|4k!756H?F9I}a^2=mie+ert z+9A3cx^YevzrR*g4kf1y37FXVqO>IlXp%Trx6aY?gM+Xd@vw^KcfrdJbe`WhB0SOy zj@om@D?orvR}oE_NA%rtBd_KZ3&M@uGtnDW;rJ={ji(`^bP*-M<$(FylubiZ29NDO zDcc22!x9G11p?03IAJ($o+)R(e`xt_4;kB<#_g0t?Z|7y`qQ6;RsNH(>g2CN12`?j z$i%^`3dEl$JEj$Bl|q(zTQVKAZ**xzSh-cEFZp(-T`e*!agh>;gPv|yB)oG zwN0_r^BtuQ?b!9rXDsfIWQaQrh;q{GP&(7Mbf%zm;05vz9iXhAg7Jap1Ob0#7!Az$ z;yr0>Uzq92V_tnnv6aJylrGI)Z}bnJqs0Gp_(?wR`z+}+`0tb=*A%?f@nVBt(?+q8 zr^#{(FGk=)V7H3o&Yi}$4zL(Y8Q*c;m?betKYw^cucvzwY7=dn&*Q!V@cF{v{X!gJ zWxe#`62ep|&i7v7@l=z0H@=i=1d>r$8MbY3NMhF0f?p~yG26-dWDxOa1m*f>FzS8O zoxo=`$5x&XfF^07`W4N;7(L_F)bBONII^a`o14v#;5bys*5=YxVuSp*j~#e0ooJZ5 z47&;y?Q;E)c!i^+i@l@VB~BFdEyeq*(*e*Vn%H(bwnLZSFSfr$d~M0SM`~}Petzix z_0!$ng#^;%Q_0Lt9#`wGg>qU(hK)G;=b#H&0-vnwzSurEAMo zW}_+PQ^V;kJ+}PoP^>A$>+a%LI)ibN6rn1byj9U8R7LR8{jZ9kA3`Q!DuU+(0XHI! zH-dh;GS^EHzQ?YVkBXwj&P*l3u$Ifsggy~k1@-FN)DXh6?;hQ{9l35}yay_jpr$x6y# zE0u)+%upAWrI`P$fOIcP-cupKQ?ue{L$vmW!GIL_ssPQ8oeaEra3v+x%~A37?7CNW zHy3lWs~rdQ9OLSJluJLI|3`iZuhO+Eb##D+q3}@4s#En6aeP28yFsxY2g=#97cGkg z4NI4GG8t-UBVR~hE<##KbbOu9YgqI6-|#&w8-4aR!1Ve!Xdd7H&8`B3ncg*7;hlHg zcOq2i;NR`K!ugZ}yWn-k9bG;3yJ}BA5H0KXD^1v)Nah^T*z=NsTbz3v`9qZ_pMxzv z`^UNCIK7(J5=?TITC0=M(g>hWfbb4#;=g+-9i%VyOj`GPc_s4RKp1nNc{bB43-nJ~ z5Gv-*5~d?9ns&{!3mKzcW)xTSam|gt{i25nL9G{qkQ)5;^==T=7-e4RlIY`wisV-q z+^xNzq&@>8R0y$9v%{j{t03u|`VxhyS^I>rFN4CSSM&T)-WFTcCqVOV`*sF35>BbZ zk}U}@h2QHZG2>6#`0*@~Q>w~+bfSb^DQZy4Z)tcx5QqM7MVH5!%rkos_3+BI#n-27 z9$oWm7e7>lBex>_2^AqcwfrN(UC>XM1mU?rz&PcJnjHtu%fET6j!?EcJcY$#z)9|P zckf=d{TayGVG@K+gHQ<`nw_f>_Yc0NW3e^czVz^u$i(fSC|WV)$dycJtfEl{=uBIF zeic-vd$cQLA7O7-K&K@a(8wn6Ou8QdrGJmtZ4RJ=gJ{joxQ$0W!zCZ)AV)gl5&6Xv zWTSD_WQ>Rjn#zHlokbYa48_@)uygx@>Y7+#Zuj{of>+3|=T*<+gjs(H+|z;5`2o-= zhkgi|fYN~%$Uk&|fqnwU2c8r3(2rD`_wWvewj8ZZ+f%~&`}Gf{roLnxJxS7a2YM(1 z_OkRy>RT_3 zkjjel8yJ#&2HtdYitp)f z&{AMkiAcU#U4I~!_iziR)&|{?Kqvy1&_m5To#M5h(cZp9fgNjkjI$I(Iqmf`@pAw0 z=)h~K4*$K~D5YZ^g;Ay&=8OB7Kp(>)09SevlRL3$2h4O~bX8%e^i!f?yqjrkV|<&a zesM=I{RN;RFOgj^b2kT(@GEm%Ez0e@0ZOjVJcM@`PSz~$AR%fu00d&QI!LdIzmp@g z*mbL!-nHMoG&I+;d5Mm0K~~whED1YrqS0`Y6?XdC)RJF3=6pO`NY7uwgy4eSvXK1M z*9pCO5L88jw<;Qkst8`X|54E{XdI>?crFm|q++hdI-4T(oFM<8PQF+)nNmUlSU+v3 zO~B)ihI-=v77Ne;5R{Sbcf(E29?4k8rM7SqE=q(EWF+yZMmVNpuC%wlqypllz3HA*rEfza;sV>hSr_~DvV?+7V{#&rU9o}3JjYKI1LIWt zbFi+|uil_>*yj1N2~=y?FWd#b*=u_J@816YfN1uxr@jd#7`?!-|bX#C+54de4?8k9^G z>qH>EyWeJY&+MnH(OF+oOy_j!(M!T0PTS%)4@O|~%;2}G&swA(`;gK<9S^=P{2~=i zc0;NpUPv*w5IZ%A#7h9~FJ_|UebO!`e}8p4R#SA;;%>m^@55fTvAdx;roQ*N$-wU1 z2QTn^zf71lhuyz-Qfil6As1d4_B-yZWG z{Px%PrFW1t%IjJ(N^4*u0Eh332I5~qf;p5PVC2VExHoycIJ&$;=||rG<>|TbGYEOtSBlaZv(Wu-wo!{SSPl^L>LvKVB?J36p>vBF!3g%(KJ3 zcu@Y;fX+hjC_W+T$Gh+PmBXrP%rVZ4udz0rNWjcT;d&vJ2JsrSy*>IyG2bZ0@{(ma(>_DwJ5ao zG0|x(crcQlO9U@UaXJgHp-)zI{oN7}dFF+seY4F_GqQWyB3PsIHz zFDKI=*pA*IZnKf-=}IOx)5LhSGr-$baYz z!|1?sfq>;hYc@aMfNFKO+7KQr&7vY;OU;!=*sV8l{=ITK^A8=q8*0=w>gU{uPOl^c zM)FfYs3FFUhEa7&5pb<~$i_e2J?ti@9H z$N)N*PijUU)Se%aSf<#$ALYHNzRC*=E-Ol}AY*-{l#k8{*tFATfn-D}ylV+hLmx)2 zZ<}+W99mgOtPZd9fAD�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�Ssr z7c^&W*j?)?9naXcpWdfa#W8v2xk=U;4I7wmA870B>+RNNP=QtJMYR%&Z;pzxvaj)3 zj~%9oJLmR3@$UVGbGaEWdgQn!9ef$-wCjmS)5@b7nnjgwjdl1hVo$C6 z#x({nSh=Bkf3vj5z20d#=__N-wW@rYMc!8XV1IW%{|}d1x+=HgdB7 Date: Mon, 19 Aug 2024 16:19:27 +0000 Subject: [PATCH 13/13] two new tests --- zingolib/src/config.rs | 12 ++++++++++ zingolib/src/wallet/disk/testing.rs | 24 +++++++++++++------- zingolib/src/wallet/disk/testing/examples.rs | 4 ++-- zingolib/src/wallet/disk/testing/tests.rs | 4 ++-- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/zingolib/src/config.rs b/zingolib/src/config.rs index c65cb5ab8..cb3677137 100644 --- a/zingolib/src/config.rs +++ b/zingolib/src/config.rs @@ -253,6 +253,18 @@ impl ZingoConfig { .create() } + #[cfg(any(test, feature = "test-elevation"))] + /// 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(), + ) + .create() + } + #[cfg(feature = "test-elevation")] /// create a ZingoConfig that signals a LightClient not to connect to a server. pub fn create_unconnected(chain: ChainType, dir: Option) -> ZingoConfig { diff --git a/zingolib/src/wallet/disk/testing.rs b/zingolib/src/wallet/disk/testing.rs index 6ef9d29d4..ac8d1d3b1 100644 --- a/zingolib/src/wallet/disk/testing.rs +++ b/zingolib/src/wallet/disk/testing.rs @@ -4,14 +4,6 @@ use super::LightWallet; impl LightWallet { - /// parses a wallet as an testnet wallet, aimed at a default testnet server - pub async fn unsafe_from_buffer_testnet(data: &[u8]) -> Self { - let config = crate::config::ZingoConfig::create_testnet(); - Self::read_internal(data, &config) - .await - .map_err(|e| format!("Cannot deserialize LightWallet file!: {}", e)) - .unwrap() - } /// connects a wallet to a local regtest node. pub async fn unsafe_from_buffer_regtest(data: &[u8]) -> Self { // this step starts a TestEnvironment and picks a new port! @@ -30,6 +22,22 @@ impl LightWallet { .map_err(|e| format!("Cannot deserialize LightWallet file!: {}", e)) .unwrap() } + /// parses a wallet as an testnet wallet, aimed at a default testnet server + pub async fn unsafe_from_buffer_testnet(data: &[u8]) -> Self { + let config = crate::config::ZingoConfig::create_testnet(); + Self::read_internal(data, &config) + .await + .map_err(|e| format!("Cannot deserialize LightWallet file!: {}", e)) + .unwrap() + } + /// parses a wallet as an testnet wallet, aimed at a default testnet server + pub async fn unsafe_from_buffer_mainnet(data: &[u8]) -> Self { + let config = crate::config::ZingoConfig::create_mainnet(); + Self::read_internal(data, &config) + .await + .map_err(|e| format!("Cannot deserialize LightWallet file!: {}", e)) + .unwrap() + } } // async fn assert_test_wallet(case: examples::LegacyWalletCase) { diff --git a/zingolib/src/wallet/disk/testing/examples.rs b/zingolib/src/wallet/disk/testing/examples.rs index 617b0973b..a8b8b2278 100644 --- a/zingolib/src/wallet/disk/testing/examples.rs +++ b/zingolib/src/wallet/disk/testing/examples.rs @@ -55,7 +55,7 @@ impl LightWallet { ExampleVTFCORFBCBPCTCFUPMEGMWBPWalletVersionCase::V28, ), ) => { - LightWallet::unsafe_from_buffer_regtest(include_bytes!( + LightWallet::unsafe_from_buffer_mainnet(include_bytes!( "examples/mainnet/vtfcorfbcbpctcfupmegmwbp/v28/zingo-wallet.dat" )) .await @@ -65,7 +65,7 @@ impl LightWallet { ExampleMSKMGDBHOTBPETCJWCSPGOPPWalletVersionCase::Gab72a38b, ), ) => { - LightWallet::unsafe_from_buffer_regtest(include_bytes!( + LightWallet::unsafe_from_buffer_testnet(include_bytes!( "examples/testnet/mskmgdbhotbpetcjwcspgopp/Gab72a38b/zingo-wallet.dat" )) .await diff --git a/zingolib/src/wallet/disk/testing/tests.rs b/zingolib/src/wallet/disk/testing/tests.rs index d01d1076a..e5ea3a644 100644 --- a/zingolib/src/wallet/disk/testing/tests.rs +++ b/zingolib/src/wallet/disk/testing/tests.rs @@ -12,7 +12,7 @@ use super::examples::LegacyWalletCaseZingoV26; #[tokio::test] async fn verify_example_wallet_mainnet_vtfcorfbcbpctcfupmegmwbp_v28() { - let wallet = + let _wallet = LightWallet::load_example_wallet(super::examples::ExampleWalletNetworkCase::Mainnet( ExampleMainnetWalletSeedCase::VTFCORFBCBPCTCFUPMEGMWBP( super::examples::ExampleVTFCORFBCBPCTCFUPMEGMWBPWalletVersionCase::V28, @@ -22,7 +22,7 @@ async fn verify_example_wallet_mainnet_vtfcorfbcbpctcfupmegmwbp_v28() { } #[tokio::test] async fn verify_example_wallet_mainnet_mskmgdbhotbpetcjwcspgopp_gab72a38b() { - let wallet = + let _wallet = LightWallet::load_example_wallet(super::examples::ExampleWalletNetworkCase::Testnet( super::examples::ExampleTestnetWalletSeedCase::MSKMGDBHOTBPETCJWCSPGOPP( super::examples::ExampleMSKMGDBHOTBPETCJWCSPGOPPWalletVersionCase::Gab72a38b,