From de4655d4c7babafa2b0af433f311c5b7574e206a Mon Sep 17 00:00:00 2001 From: zancas Date: Mon, 6 May 2024 21:24:43 -0600 Subject: [PATCH 01/13] readd update_tmamt_and_return_step_result --- zingolib/src/lightclient/send.rs | 97 ++++++++++++++++---------------- 1 file changed, 49 insertions(+), 48 deletions(-) diff --git a/zingolib/src/lightclient/send.rs b/zingolib/src/lightclient/send.rs index 3dd0610242..c64c616db8 100644 --- a/zingolib/src/lightclient/send.rs +++ b/zingolib/src/lightclient/send.rs @@ -33,38 +33,57 @@ impl LightClient { }) } - async fn iterate_proposal_send_scan( + async fn update_tmamt_and_return_step_result( + &self, + proposal: &Proposal, + step: zcash_client_backend::proposal::Step, + step_results: &Vec<( + &zcash_client_backend::proposal::Step, + zcash_primitives::transaction::builder::BuildResult, + )>, + ) -> Result { + let fee_rule = proposal.fee_rule(); + let min_target_height = proposal.min_target_height(); + let unified_spend_key = zcash_keys::keys::UnifiedSpendingKey::try_from( + self.wallet.wallet_capability().as_ref(), + ) + .map_err(DoSendProposedError::UnifiedSpendKey)?; + let (sapling_output, sapling_spend) = self + .read_sapling_params() + .map_err(DoSendProposedError::SaplingParams)?; + let sapling_prover = LocalTxProver::from_bytes(&sapling_spend, &sapling_output); + zcash_client_backend::data_api::wallet::calculate_proposed_transaction( + std::ops::DerefMut::deref_mut( + &mut self + .wallet + .transaction_context + .transaction_metadata_set + .write() + .await, + ), + &self.wallet.transaction_context.config.chain, + &sapling_prover, + &sapling_prover, + &unified_spend_key, + zcash_client_backend::wallet::OvkPolicy::Sender, + fee_rule, + min_target_height, + &step_results, + &step, + ) + .map_err(DoSendProposedError::Calculation) + } + async fn iterate_proposal_send_scan( &self, proposal: &Proposal, - sapling_prover: &(impl SpendProver + OutputProver), - unified_spend_key: &UnifiedSpendingKey, submission_height: BlockHeight, ) -> Result, DoSendProposedError> { let mut step_results = Vec::with_capacity(proposal.steps().len()); let mut txids = Vec::with_capacity(proposal.steps().len()); for step in proposal.steps() { - let step_result = { - let mut tmamt = self - .wallet - .transaction_context - .transaction_metadata_set - .write() - .await; - - zcash_client_backend::data_api::wallet::calculate_proposed_transaction( - tmamt.deref_mut(), - &self.wallet.transaction_context.config.chain, - sapling_prover, - sapling_prover, - unified_spend_key, - zcash_client_backend::wallet::OvkPolicy::Sender, - proposal.fee_rule(), - proposal.min_target_height(), - &step_results, - step, - ) - .map_err(DoSendProposedError::Calculation)? - }; + let step_result = self + .update_tmamt_and_return_step_result(proposal, step.clone(), &step_results) + .await?; let txid = self .wallet @@ -108,32 +127,14 @@ impl LightClient { .await .map_err(DoSendProposedError::SubmissionHeight)?; - let (sapling_output, sapling_spend) = self - .read_sapling_params() - .map_err(DoSendProposedError::SaplingParams)?; - let sapling_prover = LocalTxProver::from_bytes(&sapling_spend, &sapling_output); - let unified_spend_key = - UnifiedSpendingKey::try_from(self.wallet.wallet_capability().as_ref()) - .map_err(DoSendProposedError::UnifiedSpendKey)?; - match proposal { crate::lightclient::ZingoProposal::Transfer(transfer_proposal) => { - self.iterate_proposal_send_scan( - transfer_proposal, - &sapling_prover, - &unified_spend_key, - submission_height, - ) - .await + self.iterate_proposal_send_scan(transfer_proposal, submission_height) + .await } crate::lightclient::ZingoProposal::Shield(shield_proposal) => { - self.iterate_proposal_send_scan( - shield_proposal, - &sapling_prover, - &unified_spend_key, - submission_height, - ) - .await + self.iterate_proposal_send_scan(shield_proposal, submission_height) + .await } } } else { @@ -216,6 +217,6 @@ pub enum DoSendProposedError { pub enum DoQuickSendProposedError { #[error("propose {0}")] Propose(crate::lightclient::propose::DoProposeError), - #[error("No proposal. Call do_propose first.")] + #[error("Can't QuickSend! No proposal. Call do_propose first.")] Send(DoSendProposedError), } From 594c08552d7fce96feb5183898270b641fb3596f Mon Sep 17 00:00:00 2001 From: zancas Date: Mon, 6 May 2024 21:30:37 -0600 Subject: [PATCH 02/13] readd calls to update_latest_proposal --- zingolib/src/lightclient/propose.rs | 11 ++++------- zingolib/src/lightclient/send.rs | 8 ++------ 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/zingolib/src/lightclient/propose.rs b/zingolib/src/lightclient/propose.rs index 5ca5b32191..54fd1829a9 100644 --- a/zingolib/src/lightclient/propose.rs +++ b/zingolib/src/lightclient/propose.rs @@ -170,10 +170,8 @@ impl LightClient { ) .map_err(DoProposeError::Proposal)?; - let mut latest_proposal_lock = self.latest_proposal.write().await; - *latest_proposal_lock = Some(crate::data::proposal::ZingoProposal::Transfer( - proposal.clone(), - )); + self.update_latest_proposal(ZingoProposal::Transfer(proposal.clone())) + .await; Ok(proposal) } @@ -246,9 +244,8 @@ impl LightClient { ) .map_err(DoProposeError::ShieldProposal)?; - *self.latest_proposal.write().await = Some(crate::data::proposal::ZingoProposal::Shield( - proposed_shield.clone(), - )); + self.update_latest_proposal(ZingoProposal::Shield(proposed_shield.clone())) + .await; Ok(proposed_shield) } /// A helper method that standardizes latest_proposal update diff --git a/zingolib/src/lightclient/send.rs b/zingolib/src/lightclient/send.rs index c64c616db8..2e81d992cf 100644 --- a/zingolib/src/lightclient/send.rs +++ b/zingolib/src/lightclient/send.rs @@ -1,13 +1,7 @@ //! TODO: Add Mod Description Here! -use std::ops::DerefMut; use nonempty::NonEmpty; -use sapling_crypto::prover::OutputProver; -use sapling_crypto::prover::SpendProver; - -use zcash_keys::keys::UnifiedSpendingKey; - use zcash_client_backend::{proposal::Proposal, zip321::TransactionRequest}; use zcash_primitives::{consensus::BlockHeight, transaction::TxId}; use zcash_proofs::prover::LocalTxProver; @@ -177,10 +171,12 @@ mod test { .await .expect("A client!"); let proposal = ProposalBuilder::new().build(); + /* let step = zcash_client_backend::proposal::Step::from_parts(); let step_result = client .update_tmamt_and_return_step_result(&proposal, step, step_results) .await; + */ } } From 44fe308d61950206cd6844f72f62610732d505c7 Mon Sep 17 00:00:00 2001 From: zancas Date: Mon, 6 May 2024 21:43:07 -0600 Subject: [PATCH 03/13] more test framework --- zingolib/src/lightclient/send.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/zingolib/src/lightclient/send.rs b/zingolib/src/lightclient/send.rs index 2e81d992cf..74d1a008c1 100644 --- a/zingolib/src/lightclient/send.rs +++ b/zingolib/src/lightclient/send.rs @@ -158,7 +158,10 @@ mod test { use zingo_testvectors::seeds::HOSPITAL_MUSEUM_SEED; use zingoconfig::ZingoConfigBuilder; - use crate::{lightclient::LightClient, test_framework::mocks::ProposalBuilder}; + use crate::{ + lightclient::LightClient, + test_framework::mocks::{ProposalBuilder, StepBuilder}, + }; #[tokio::test] async fn update_tmamt_and_return_step_result() { @@ -171,12 +174,14 @@ mod test { .await .expect("A client!"); let proposal = ProposalBuilder::new().build(); - /* - let step = zcash_client_backend::proposal::Step::from_parts(); + let step = StepBuilder::new().build(); + let step_results: Vec<( + &zcash_client_backend::proposal::Step, + zcash_primitives::transaction::builder::BuildResult, + )> = vec![]; let step_result = client - .update_tmamt_and_return_step_result(&proposal, step, step_results) + .update_tmamt_and_return_step_result(&proposal, step, &step_results) .await; - */ } } From d11a615c3687be3a970c2dfd675398ce56510054 Mon Sep 17 00:00:00 2001 From: zancas Date: Mon, 6 May 2024 21:57:24 -0600 Subject: [PATCH 04/13] found unwrap None! Will address immediately. --- zingolib/src/lightclient/send.rs | 6 ++++++ zingolib/src/test_framework/mocks.rs | 3 +++ 2 files changed, 9 insertions(+) diff --git a/zingolib/src/lightclient/send.rs b/zingolib/src/lightclient/send.rs index 74d1a008c1..d01fde2047 100644 --- a/zingolib/src/lightclient/send.rs +++ b/zingolib/src/lightclient/send.rs @@ -165,7 +165,9 @@ mod test { #[tokio::test] async fn update_tmamt_and_return_step_result() { + dbg!("Begin test fn 1"); let config = ZingoConfigBuilder::default().create(); + dbg!("Begin test fn 2"); let client = LightClient::create_unconnected( &config, crate::wallet::WalletBase::MnemonicPhrase(HOSPITAL_MUSEUM_SEED.to_string()), @@ -173,12 +175,16 @@ mod test { ) .await .expect("A client!"); + dbg!("Begin test fn 3"); let proposal = ProposalBuilder::new().build(); + dbg!("Begin test fn 4"); let step = StepBuilder::new().build(); + dbg!("Begin test fn 5"); let step_results: Vec<( &zcash_client_backend::proposal::Step, zcash_primitives::transaction::builder::BuildResult, )> = vec![]; + dbg!("Here?"); let step_result = client .update_tmamt_and_return_step_result(&proposal, step, &step_results) .await; diff --git a/zingolib/src/test_framework/mocks.rs b/zingolib/src/test_framework/mocks.rs index 6efb51c69b..921b520d6f 100644 --- a/zingolib/src/test_framework/mocks.rs +++ b/zingolib/src/test_framework/mocks.rs @@ -324,7 +324,9 @@ pub mod proposal { /// `build` will panic if any fields of the builder are `None` or if the build failed /// due to invalid values. pub fn build(self) -> Proposal { + dbg!("Inside Proposal Builder new"); let step = self.steps.unwrap().first().clone(); + dbg!("Ooopppsss!"); Proposal::single_step( step.transaction_request().clone(), step.payment_pools().clone(), @@ -401,6 +403,7 @@ pub mod proposal { /// due to invalid values. #[allow(dead_code)] pub fn build(self) -> Step { + dbg!("building!"); Step::from_parts( &[], self.transaction_request.unwrap(), From 3e3839d290476acb1b25f131692234462de16fe8 Mon Sep 17 00:00:00 2001 From: Hazel OHearn Date: Tue, 7 May 2024 17:15:29 -0300 Subject: [PATCH 05/13] untested get_transparent_receivers --- Cargo.lock | 163 +++++++++--------- .../blaze/block_management_reorg_detection.rs | 12 +- zingolib/src/lightclient/propose.rs | 17 +- zingolib/src/wallet.rs | 8 +- .../src/wallet/keys/extended_transparent.rs | 10 +- zingolib/src/wallet/keys/unified.rs | 109 ++++++------ zingolib/src/wallet/tx_map_and_maybe_trees.rs | 48 +++++- .../src/wallet/tx_map_and_maybe_trees/get.rs | 2 +- .../tx_map_and_maybe_trees/read_write.rs | 4 +- .../trait_walletread.rs | 62 ++++++- 10 files changed, 260 insertions(+), 175 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bb3382b93b..7a53ff25e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -64,47 +64,48 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -112,9 +113,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.82" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" [[package]] name = "append-only-vec" @@ -158,7 +159,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -169,14 +170,14 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] name = "autocfg" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "axum" @@ -460,9 +461,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.95" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32a725bc159af97c3e629873bb9f88fb8cf8a4867175f76dc987815ea07c83b" +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" [[package]] name = "cfg-if" @@ -557,9 +558,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "concat-idents" @@ -568,7 +569,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f76990911f2267d837d9d0ad060aa63aaad170af40904b29461734c339030d4d" dependencies = [ "quote", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -1049,7 +1050,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -1094,9 +1095,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -1575,6 +1576,12 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + [[package]] name = "itertools" version = "0.10.5" @@ -1648,9 +1655,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.153" +version = "0.2.154" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" [[package]] name = "libm" @@ -1889,11 +1896,10 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -1915,9 +1921,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -1977,7 +1983,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -2150,7 +2156,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -2205,12 +2211,12 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "prettyplease" -version = "0.2.19" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ac2cf0f2e4f42b49f5ffd07dae8d746508ef7526c13940e5f524012ae6c6550" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -2239,9 +2245,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] @@ -2293,7 +2299,7 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.60", + "syn 2.0.61", "tempfile", ] @@ -2307,7 +2313,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -2662,7 +2668,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.60", + "syn 2.0.61", "walkdir", ] @@ -2678,9 +2684,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc_version" @@ -2761,9 +2767,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.5.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beb461507cee2c2ff151784c52762cf4d9ff6a61f3e80968600ed24fa837fa54" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" [[package]] name = "rustls-webpki" @@ -2777,9 +2783,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" +checksum = "092474d1a01ea8278f69e6a358998405fae5b8b963ddaeb2b0b04a128bf1dfb0" [[package]] name = "rusty-fork" @@ -2818,9 +2824,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -2917,11 +2923,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", "core-foundation", "core-foundation-sys", "libc", @@ -2930,9 +2936,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" dependencies = [ "core-foundation-sys", "libc", @@ -2940,15 +2946,15 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.199" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c9f6e76df036c77cd94996771fb40db98187f096dd0b9af39c6c6e452ba966a" +checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" dependencies = [ "serde_derive", ] @@ -2965,13 +2971,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.199" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11bd257a6541e141e42ca6d24ae26f7714887b47e89aa739099104c7e4d3b7fc" +checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -3166,9 +3172,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.60" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -3248,7 +3254,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -3259,28 +3265,28 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.61", "test-case-core", ] [[package]] name = "thiserror" -version = "1.0.59" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" +checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.59" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" +checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -3374,7 +3380,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -3421,16 +3427,15 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes 1.6.0", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] @@ -3475,7 +3480,7 @@ dependencies = [ "proc-macro2", "prost-build", "quote", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -3548,7 +3553,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -3812,7 +3817,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.61", "wasm-bindgen-shared", ] @@ -3846,7 +3851,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.61", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4317,7 +4322,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] diff --git a/zingolib/src/blaze/block_management_reorg_detection.rs b/zingolib/src/blaze/block_management_reorg_detection.rs index 2b700eb861..bd15aca0bf 100644 --- a/zingolib/src/blaze/block_management_reorg_detection.rs +++ b/zingolib/src/blaze/block_management_reorg_detection.rs @@ -841,7 +841,9 @@ mod tests { .handle_reorgs_and_populate_block_mangement_data( start_block, end_block, - Arc::new(RwLock::new(TxMapAndMaybeTrees::new_with_witness_trees())), + Arc::new(RwLock::new( + TxMapAndMaybeTrees::new_with_witness_trees_address_free(), + )), reorg_transmitter, ) .await; @@ -890,7 +892,9 @@ mod tests { .handle_reorgs_and_populate_block_mangement_data( start_block, end_block, - Arc::new(RwLock::new(TxMapAndMaybeTrees::new_with_witness_trees())), + Arc::new(RwLock::new( + TxMapAndMaybeTrees::new_with_witness_trees_address_free(), + )), reorg_transmitter, ) .await; @@ -986,7 +990,9 @@ mod tests { .handle_reorgs_and_populate_block_mangement_data( start_block, end_block, - Arc::new(RwLock::new(TxMapAndMaybeTrees::new_with_witness_trees())), + Arc::new(RwLock::new( + TxMapAndMaybeTrees::new_with_witness_trees_address_free(), + )), reorg_transmitter, ) .await; diff --git a/zingolib/src/lightclient/propose.rs b/zingolib/src/lightclient/propose.rs index 54fd1829a9..75d28fd7da 100644 --- a/zingolib/src/lightclient/propose.rs +++ b/zingolib/src/lightclient/propose.rs @@ -178,23 +178,12 @@ impl LightClient { fn get_transparent_addresses( &self, ) -> Result, DoProposeError> { - let secp = secp256k1::Secp256k1::new(); Ok(self .wallet .wallet_capability() - .transparent_child_keys() - .map_err(|_e| { - DoProposeError::ShieldProposal( - zcash_client_backend::data_api::error::Error::DataSource( - TxMapAndMaybeTreesTraitError::NoSpendCapability, - ), - ) - })? + .transparent_child_addresses() .iter() - .map(|(_index, sk)| { - #[allow(deprecated)] - zcash_primitives::legacy::keys::pubkey_to_address(&sk.public_key(&secp)) - }) + .map(|(_index, sk)| *sk) .collect::>()) } /// The shield operation consumes a proposal that transfers value @@ -237,7 +226,7 @@ impl LightClient { &input_selector, // don't shield dust NonNegativeAmount::const_from_u64(10_000), - &self.get_transparent_addresses()?, + &dbg!(self.get_transparent_addresses()?), // review! do we want to require confirmations? // make it configurable? 0, diff --git a/zingolib/src/wallet.rs b/zingolib/src/wallet.rs index a5533419f8..ec39b3f62f 100644 --- a/zingolib/src/wallet.rs +++ b/zingolib/src/wallet.rs @@ -370,9 +370,13 @@ impl LightWallet { )); }; let transaction_metadata_set = if wc.can_spend_from_all_pools() { - Arc::new(RwLock::new(TxMapAndMaybeTrees::new_with_witness_trees())) + Arc::new(RwLock::new(TxMapAndMaybeTrees::new_with_witness_trees( + wc.transparent_child_addresses().clone(), + ))) } else { - Arc::new(RwLock::new(TxMapAndMaybeTrees::new_treeless())) + Arc::new(RwLock::new(TxMapAndMaybeTrees::new_treeless( + wc.transparent_child_addresses().clone(), + ))) }; let transaction_context = TransactionContext::new(&config, Arc::new(wc), transaction_metadata_set); diff --git a/zingolib/src/wallet/keys/extended_transparent.rs b/zingolib/src/wallet/keys/extended_transparent.rs index 30cb1cf2b8..3f04e14e46 100644 --- a/zingolib/src/wallet/keys/extended_transparent.rs +++ b/zingolib/src/wallet/keys/extended_transparent.rs @@ -48,18 +48,18 @@ impl KeyIndex { } /// Generate KeyIndex from raw index value. - pub fn from_index(i: u32) -> Result { + pub fn from_index(i: u32) -> Self { if i < HARDENED_KEY_START_INDEX { - Ok(KeyIndex::Normal(i)) + KeyIndex::Normal(i) } else { - Ok(KeyIndex::Hardened(i)) + KeyIndex::Hardened(i) } } } impl From for KeyIndex { fn from(index: u32) -> Self { - KeyIndex::from_index(index).expect("KeyIndex") + KeyIndex::from_index(index) } } @@ -278,7 +278,7 @@ fn test_commutativity_of_key_derivation_mechanisms() { // pk ---> pk_i // initial key derivation material - let i = KeyIndex::from_index(42).unwrap(); + let i = KeyIndex::from_index(42); let sk = ExtendedPrivKey::with_seed(&[0xcd; 64]).unwrap(); // sk -> sk_i -> pk_i derivation diff --git a/zingolib/src/wallet/keys/unified.rs b/zingolib/src/wallet/keys/unified.rs index 6cb12737e0..2cee300b97 100644 --- a/zingolib/src/wallet/keys/unified.rs +++ b/zingolib/src/wallet/keys/unified.rs @@ -1,11 +1,11 @@ //! TODO: Add Mod Discription Here! -use std::marker::PhantomData; use std::sync::atomic; use std::{ collections::{HashMap, HashSet}, io::{self, Read, Write}, sync::atomic::AtomicBool, }; +use std::{marker::PhantomData, sync::Arc}; use append_only_vec::AppendOnlyVec; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; @@ -83,7 +83,7 @@ pub struct WalletCapability { /// TODO: Add Doc Comment Here! pub orchard: Capability, - transparent_child_keys: append_only_vec::AppendOnlyVec<(usize, secp256k1::SecretKey)>, + transparent_child_addresses: Arc>, addresses: append_only_vec::AppendOnlyVec, // Not all diversifier indexes produce valid sapling addresses. // Because of this, the index isn't necessarily equal to addresses.len() @@ -95,7 +95,7 @@ impl Default for WalletCapability { orchard: Capability::None, sapling: Capability::None, transparent: Capability::None, - transparent_child_keys: AppendOnlyVec::new(), + transparent_child_addresses: Arc::new(AppendOnlyVec::new()), addresses: AppendOnlyVec::new(), addresses_write_lock: AtomicBool::new(false), } @@ -174,14 +174,8 @@ impl WalletCapability { } /// TODO: Add Doc Comment Here! - pub fn transparent_child_keys( - &self, - ) -> Result<&AppendOnlyVec<(usize, secp256k1::SecretKey)>, String> { - if self.transparent.can_spend() { - Ok(&self.transparent_child_keys) - } else { - Err("The wallet is not capable of spending transparent funds.".to_string()) - } + pub fn transparent_child_addresses(&self) -> &Arc> { + &self.transparent_child_addresses } /// TODO: Add Doc Comment Here! @@ -261,35 +255,43 @@ impl WalletCapability { }; let transparent_receiver = if desired_receivers.transparent { - let child_index = KeyIndex::from_index(self.addresses.len() as u32).unwrap(); - match &self.transparent { + let child_index = KeyIndex::from_index(self.addresses.len() as u32); + let child_pk = match &self.transparent { Capability::Spend(ext_sk) => { - let child_sk = match ext_sk.derive_private_key(child_index) { - Err(e) => { - self.addresses_write_lock - .swap(false, atomic::Ordering::Release); - return Err(format!("Transparent private key derivation failed: {e}")); - } - Ok(res) => res.private_key, - }; let secp = secp256k1::Secp256k1::new(); - let child_pk = secp256k1::PublicKey::from_secret_key(&secp, &child_sk); - self.transparent_child_keys - .push((self.addresses.len(), child_sk)); - Some(child_pk) - } - Capability::View(ext_pk) => { - let child_pk = match ext_pk.derive_public_key(child_index) { - Err(e) => { - self.addresses_write_lock - .swap(false, atomic::Ordering::Release); - return Err(format!("Transparent public key derivation failed: {e}")); + Some( + match ext_sk.derive_private_key(child_index) { + Err(e) => { + self.addresses_write_lock + .swap(false, atomic::Ordering::Release); + return Err(format!( + "Transparent private key derivation failed: {e}" + )); + } + Ok(res) => res.private_key, } - Ok(res) => res.public_key, - }; - Some(child_pk) + .public_key(&secp), + ) } + Capability::View(ext_pk) => Some(match ext_pk.derive_public_key(child_index) { + Err(e) => { + self.addresses_write_lock + .swap(false, atomic::Ordering::Release); + return Err(format!("Transparent public key derivation failed: {e}")); + } + Ok(res) => res.public_key, + }), Capability::None => None, + }; + if let Some(pk) = child_pk { + self.transparent_child_addresses.push(( + self.addresses.len(), + #[allow(deprecated)] + zcash_primitives::legacy::keys::pubkey_to_address(&pk), + )); + Some(pk) + } else { + None } } else { None @@ -328,29 +330,23 @@ impl WalletCapability { &self, config: &ZingoConfig, ) -> Result, String> { - if self.transparent.can_spend() { - Ok(self - .addresses + if let Capability::Spend(transparent_sk) = &self.transparent { + self.transparent_child_addresses() .iter() - .enumerate() - .filter_map(|(i, ua)| { - ua.transparent().zip( - self.transparent_child_keys - .iter() - .find(|(index, _key)| i == *index), - ) - }) - .map(|(taddr, key)| { + .map(|(i, taddr)| -> Result<_, String> { let hash = match taddr { TransparentAddress::PublicKeyHash(hash) => hash, TransparentAddress::ScriptHash(hash) => hash, }; - ( + Ok(( hash.to_base58check(&config.chain.b58_pubkey_address_prefix(), &[]), - key.1, - ) + transparent_sk + .derive_private_key(KeyIndex::Normal(*i as u32)) + .map_err(|e| e.to_string())? + .private_key, + )) }) - .collect()) + .collect::>() } else { Err("Wallet is no capable to spend transparent funds".to_string()) } @@ -864,11 +860,14 @@ pub async fn get_transparent_secretkey_pubkey_taddr( let child_ext_pk = ext_pk.derive_public_key(KeyIndex::Normal(0)).ok(); (None, child_ext_pk.map(|x| x.public_key)) } - Capability::Spend(_) => { - let sk = wc.transparent_child_keys[0].1; + Capability::Spend(master_sk) => { let secp = secp256k1::Secp256k1::new(); - let pk = secp256k1::PublicKey::from_secret_key(&secp, &sk); - (Some(sk), Some(pk)) + let extsk = master_sk + .derive_private_key(KeyIndex::Normal(wc.transparent_child_addresses[0].0 as u32)) + .unwrap(); + let pk = extsk.private_key.public_key(&secp); + #[allow(deprecated)] + (Some(extsk.private_key), Some(pk)) } }; let taddr = wc.addresses()[0] diff --git a/zingolib/src/wallet/tx_map_and_maybe_trees.rs b/zingolib/src/wallet/tx_map_and_maybe_trees.rs index 2ee7b607eb..d5e58ffdc3 100644 --- a/zingolib/src/wallet/tx_map_and_maybe_trees.rs +++ b/zingolib/src/wallet/tx_map_and_maybe_trees.rs @@ -4,8 +4,14 @@ //! associated types for TxMapAndMaybeTrees that have no relevance elsewhere. use crate::{ - data::witness_trees::WitnessTrees, wallet::transaction_records_by_id::TransactionRecordsById, + data::witness_trees::WitnessTrees, + wallet::transaction_records_by_id::{ + trait_inputsource::InputSourceError, TransactionRecordsById, + }, }; +use std::{fmt::Debug, sync::Arc}; +use thiserror::Error; +use zcash_primitives::legacy::TransparentAddress; /// HashMap of all transactions in a wallet, keyed by txid. /// Note that the parent is expected to hold a RwLock, so we will assume that all accesses to @@ -13,6 +19,8 @@ use crate::{ pub struct TxMapAndMaybeTrees { pub transaction_records_by_id: TransactionRecordsById, witness_trees: Option, + pub(crate) transparent_child_addresses: + Arc>, } pub mod get; @@ -20,16 +28,26 @@ pub mod read_write; pub mod recording; impl TxMapAndMaybeTrees { - pub(crate) fn new_with_witness_trees() -> TxMapAndMaybeTrees { + pub(crate) fn new_with_witness_trees( + transparent_child_addresses: Arc< + append_only_vec::AppendOnlyVec<(usize, TransparentAddress)>, + >, + ) -> TxMapAndMaybeTrees { Self { transaction_records_by_id: TransactionRecordsById::new(), witness_trees: Some(WitnessTrees::default()), + transparent_child_addresses, } } - pub(crate) fn new_treeless() -> TxMapAndMaybeTrees { + pub(crate) fn new_treeless( + transparent_child_addresses: Arc< + append_only_vec::AppendOnlyVec<(usize, TransparentAddress)>, + >, + ) -> TxMapAndMaybeTrees { Self { transaction_records_by_id: TransactionRecordsById::new(), witness_trees: None, + transparent_child_addresses, } } pub fn witness_trees(&self) -> Option<&WitnessTrees> { @@ -43,11 +61,25 @@ impl TxMapAndMaybeTrees { self.witness_trees.as_mut().map(WitnessTrees::clear); } } - -use std::fmt::Debug; -use thiserror::Error; - -use crate::wallet::transaction_records_by_id::trait_inputsource::InputSourceError; +#[cfg(test)] +impl TxMapAndMaybeTrees { + /// For any unit tests that don't require a WalletCapability, where the addresses come from + pub(crate) fn new_with_witness_trees_address_free() -> TxMapAndMaybeTrees { + Self { + transaction_records_by_id: TransactionRecordsById::new(), + witness_trees: Some(WitnessTrees::default()), + transparent_child_addresses: Arc::new(append_only_vec::AppendOnlyVec::new()), + } + } + /// For any unit tests that don't require a WalletCapability, where the addresses come from + pub(crate) fn new_with_treeless_address_free() -> TxMapAndMaybeTrees { + Self { + transaction_records_by_id: TransactionRecordsById::new(), + witness_trees: None, + transparent_child_addresses: Arc::new(append_only_vec::AppendOnlyVec::new()), + } + } +} #[derive(Debug, PartialEq, Error)] pub enum TxMapAndMaybeTreesTraitError { diff --git a/zingolib/src/wallet/tx_map_and_maybe_trees/get.rs b/zingolib/src/wallet/tx_map_and_maybe_trees/get.rs index c3c3685adc..30a04856bb 100644 --- a/zingolib/src/wallet/tx_map_and_maybe_trees/get.rs +++ b/zingolib/src/wallet/tx_map_and_maybe_trees/get.rs @@ -136,7 +136,7 @@ impl TxMapAndMaybeTrees { #[test] fn test_get_some_txid_from_highest_wallet_block() { - let mut tms = TxMapAndMaybeTrees::new_treeless(); + let mut tms = TxMapAndMaybeTrees::new_with_treeless_address_free(); assert_eq!(tms.get_some_txid_from_highest_wallet_block(), None); let txid_bytes_1 = [0u8; 32]; let txid_bytes_2 = [1u8; 32]; diff --git a/zingolib/src/wallet/tx_map_and_maybe_trees/read_write.rs b/zingolib/src/wallet/tx_map_and_maybe_trees/read_write.rs index 2b333223ce..131cc06d38 100644 --- a/zingolib/src/wallet/tx_map_and_maybe_trees/read_write.rs +++ b/zingolib/src/wallet/tx_map_and_maybe_trees/read_write.rs @@ -67,6 +67,7 @@ impl TxMapAndMaybeTrees { Ok(Self { transaction_records_by_id: map, witness_trees, + transparent_child_addresses: wallet_capability.transparent_child_addresses().clone(), }) } @@ -132,6 +133,7 @@ impl TxMapAndMaybeTrees { Ok(Self { transaction_records_by_id: TransactionRecordsById::from_map(map), witness_trees, + transparent_child_addresses: wallet_capability.transparent_child_addresses().clone(), }) } @@ -167,7 +169,7 @@ mod tests { #[tokio::test] async fn test_write() { - let mut tms = TxMapAndMaybeTrees::new_with_witness_trees(); + let mut tms = TxMapAndMaybeTrees::new_with_witness_trees_address_free(); let mut buffer = Cursor::new(Vec::new()); // Perform the write operation diff --git a/zingolib/src/wallet/tx_map_and_maybe_trees/trait_walletread.rs b/zingolib/src/wallet/tx_map_and_maybe_trees/trait_walletread.rs index 28737dc304..1f944b6f98 100644 --- a/zingolib/src/wallet/tx_map_and_maybe_trees/trait_walletread.rs +++ b/zingolib/src/wallet/tx_map_and_maybe_trees/trait_walletread.rs @@ -5,9 +5,13 @@ use shardtree::store::ShardStore; use zcash_client_backend::{ data_api::{Account, WalletRead}, keys::UnifiedFullViewingKey, + wallet::TransparentAddressMetadata, }; -use zcash_primitives::consensus::BlockHeight; -use zip32::AccountId; +use zcash_primitives::{ + consensus::BlockHeight, + legacy::keys::{NonHardenedChildIndex, TransparentKeyScope}, +}; +use zip32::{AccountId, Scope}; use crate::wallet::notes::query::QueryStipulations; @@ -282,6 +286,47 @@ impl WalletRead for TxMapAndMaybeTrees { ) -> Result, Self::Error> { unimplemented!() } + + fn get_transparent_receivers( + &self, + _account: Self::AccountId, + ) -> Result< + std::collections::HashMap< + zcash_primitives::legacy::TransparentAddress, + Option, + >, + Self::Error, + > { + Ok(self + .transparent_child_addresses + .iter() + .map(|(index, taddr)| { + ( + *taddr, + NonHardenedChildIndex::from_index(*index as u32).map(|nhc_index| { + TransparentAddressMetadata::new( + TransparentKeyScope::from(Scope::External), + nhc_index, + ) + }), + ) + }) + .collect()) + } + + fn get_transparent_balances( + &self, + _account: Self::AccountId, + _max_height: BlockHeight, + ) -> Result< + std::collections::HashMap< + zcash_primitives::legacy::TransparentAddress, + zcash_primitives::transaction::components::amount::NonNegativeAmount, + >, + Self::Error, + > { + Ok(std::collections::HashMap::new()) + } } #[cfg(test)] @@ -309,7 +354,8 @@ mod tests { #[test] fn get_target_and_anchor_heights() { - let mut transaction_records_and_maybe_trees = TxMapAndMaybeTrees::new_with_witness_trees(); + let mut transaction_records_and_maybe_trees = + TxMapAndMaybeTrees::new_with_witness_trees_address_free(); transaction_records_and_maybe_trees .witness_trees .as_mut() @@ -327,7 +373,8 @@ mod tests { #[test] fn get_target_and_anchor_heights_none() { - let transaction_records_and_maybe_trees = TxMapAndMaybeTrees::new_with_witness_trees(); + let transaction_records_and_maybe_trees = + TxMapAndMaybeTrees::new_with_witness_trees_address_free(); assert_eq!( transaction_records_and_maybe_trees .get_target_and_anchor_heights(NonZeroU32::new(10).unwrap()) @@ -338,7 +385,8 @@ mod tests { #[test] fn get_target_and_anchor_heights_err() { - let transaction_records_and_maybe_trees = TxMapAndMaybeTrees::new_treeless(); + let transaction_records_and_maybe_trees = + TxMapAndMaybeTrees::new_with_treeless_address_free(); assert_eq!( transaction_records_and_maybe_trees .get_target_and_anchor_heights(NonZeroU32::new(10).unwrap()) @@ -351,7 +399,7 @@ mod tests { proptest! { #[test] fn get_min_unspent_height(sapling_height: u32, orchard_height: u32) { - let mut transaction_records_and_maybe_trees = TxMapAndMaybeTrees::new_with_witness_trees(); + let mut transaction_records_and_maybe_trees = TxMapAndMaybeTrees::new_with_witness_trees_address_free(); // these first three outputs will not trigger min_unspent_note transaction_records_and_maybe_trees @@ -412,7 +460,7 @@ mod tests { #[test] fn get_tx_height(tx_height: u32) { - let mut transaction_records_and_maybe_trees = TxMapAndMaybeTrees::new_with_witness_trees(); + let mut transaction_records_and_maybe_trees = TxMapAndMaybeTrees::new_with_witness_trees_address_free(); let transaction_record = TransactionRecordBuilder::default().randomize_txid().status(Confirmed(tx_height.into())) .clone() From 3748d15e127a1b9a98f991febc7a3646d03c5f7c Mon Sep 17 00:00:00 2001 From: zancas Date: Tue, 7 May 2024 09:50:44 -0600 Subject: [PATCH 06/13] gate hack to match darkside txid in production!! reorder send_to_addresses_inner reorder again and define helper start gating darkside hack feature gate compare_txids express as explicit mutual exclusion --- zingolib/src/wallet/send.rs | 43 +++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/zingolib/src/wallet/send.rs b/zingolib/src/wallet/send.rs index c0f8b08f24..50a7a17673 100644 --- a/zingolib/src/wallet/send.rs +++ b/zingolib/src/wallet/send.rs @@ -834,6 +834,25 @@ impl LightWallet { Ok(tx_builder) } + #[cfg(feature = "darkside_tests")] + async fn get_darkside_txid( + transaction: &Transaction, + broadcast_fn: F, + ) -> Result + where + F: Fn(Box<[u8]>) -> Fut, + Fut: Future>, + { + let mut raw_transaction = vec![]; + transaction.write(&mut raw_transaction).unwrap(); + let serverz_transaction_id = + broadcast_fn(raw_transaction.clone().into_boxed_slice()).await?; + if let Ok(serverz_txid_bytes) = dbg!(serverz_transaction_id).into_bytes().try_into() { + Ok(TxId::from_bytes(serverz_txid_bytes)) + } else { + Err("Couldn't transfrom string to bytes.".to_string()) + } + } pub(crate) async fn send_to_addresses_inner( &self, transaction: &Transaction, @@ -848,13 +867,6 @@ impl LightWallet { self.send_progress.write().await.is_send_in_progress = false; } - // Create the transaction bytes - let mut raw_transaction = vec![]; - transaction.write(&mut raw_transaction).unwrap(); - - let serverz_transaction_id = - broadcast_fn(raw_transaction.clone().into_boxed_slice()).await?; - // Add this transaction to the mempool structure { let price = self.price.read().await.clone(); @@ -865,22 +877,11 @@ impl LightWallet { .await; } + #[cfg(not(feature = "darkside_tests"))] let txid = transaction.txid(); - if let Ok(serverz_txid_bytes) = dbg!(serverz_transaction_id).into_bytes().try_into() { - let serverz_txid = TxId::from_bytes(serverz_txid_bytes); - if txid != serverz_txid { - // happens during darkside tests - dbg!( - "served txid {} does not match calulated txid {}", - serverz_txid, - txid, - ); - if self.transaction_context.config.accept_server_txids { - return Ok(serverz_txid); - } - } - } + #[cfg(feature = "darkside_tests")] + let txid = LightWallet::get_darkside_txid(transaction, broadcast_fn).await?; Ok(txid) } From 8641c016a6c942d1d2a28e1c1fcc506126143409 Mon Sep 17 00:00:00 2001 From: zancas Date: Tue, 7 May 2024 16:08:39 -0600 Subject: [PATCH 07/13] fix clippy suggestions --- zingolib/src/lightclient/send.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zingolib/src/lightclient/send.rs b/zingolib/src/lightclient/send.rs index d01fde2047..0dae3239d5 100644 --- a/zingolib/src/lightclient/send.rs +++ b/zingolib/src/lightclient/send.rs @@ -31,10 +31,10 @@ impl LightClient { &self, proposal: &Proposal, step: zcash_client_backend::proposal::Step, - step_results: &Vec<( + step_results: &[( &zcash_client_backend::proposal::Step, zcash_primitives::transaction::builder::BuildResult, - )>, + )], ) -> Result { let fee_rule = proposal.fee_rule(); let min_target_height = proposal.min_target_height(); @@ -62,7 +62,7 @@ impl LightClient { zcash_client_backend::wallet::OvkPolicy::Sender, fee_rule, min_target_height, - &step_results, + step_results, &step, ) .map_err(DoSendProposedError::Calculation) From 33818796cc03ecea11ffe26ee9aa185de96fd039 Mon Sep 17 00:00:00 2001 From: zancas Date: Tue, 7 May 2024 19:39:51 -0600 Subject: [PATCH 08/13] make basic default unit test run --- zingolib/src/lightclient/send.rs | 5 ++--- zingolib/src/test_framework/mocks.rs | 4 +++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/zingolib/src/lightclient/send.rs b/zingolib/src/lightclient/send.rs index 0dae3239d5..6c0986605b 100644 --- a/zingolib/src/lightclient/send.rs +++ b/zingolib/src/lightclient/send.rs @@ -176,10 +176,9 @@ mod test { .await .expect("A client!"); dbg!("Begin test fn 3"); - let proposal = ProposalBuilder::new().build(); + let proposal = ProposalBuilder::default().build(); dbg!("Begin test fn 4"); - let step = StepBuilder::new().build(); - dbg!("Begin test fn 5"); + let step = StepBuilder::default().build(); let step_results: Vec<( &zcash_client_backend::proposal::Step, zcash_primitives::transaction::builder::BuildResult, diff --git a/zingolib/src/test_framework/mocks.rs b/zingolib/src/test_framework/mocks.rs index 921b520d6f..8f276a51fe 100644 --- a/zingolib/src/test_framework/mocks.rs +++ b/zingolib/src/test_framework/mocks.rs @@ -324,7 +324,7 @@ pub mod proposal { /// `build` will panic if any fields of the builder are `None` or if the build failed /// due to invalid values. pub fn build(self) -> Proposal { - dbg!("Inside Proposal Builder new"); + dbg!("Inside Proposal Builder build"); let step = self.steps.unwrap().first().clone(); dbg!("Ooopppsss!"); Proposal::single_step( @@ -344,7 +344,9 @@ pub mod proposal { impl Default for ProposalBuilder { /// Constructs a new [`ProposalBuilder`] where all fields are preset to default values. fn default() -> Self { + dbg!("Inside ProposalBuilder default about to call new()."); let mut builder = ProposalBuilder::new(); + dbg!("Inside default about to build."); builder .fee_rule(FeeRule::standard()) .min_target_height(BlockHeight::from_u32(1)) From 37ba054003c7cf903ac9f7cf007904ab8bf95051 Mon Sep 17 00:00:00 2001 From: zancas Date: Wed, 8 May 2024 06:15:07 -0600 Subject: [PATCH 09/13] show default build Err --- zingolib/src/lightclient/send.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/zingolib/src/lightclient/send.rs b/zingolib/src/lightclient/send.rs index 6c0986605b..a4500eb61e 100644 --- a/zingolib/src/lightclient/send.rs +++ b/zingolib/src/lightclient/send.rs @@ -165,9 +165,7 @@ mod test { #[tokio::test] async fn update_tmamt_and_return_step_result() { - dbg!("Begin test fn 1"); let config = ZingoConfigBuilder::default().create(); - dbg!("Begin test fn 2"); let client = LightClient::create_unconnected( &config, crate::wallet::WalletBase::MnemonicPhrase(HOSPITAL_MUSEUM_SEED.to_string()), @@ -175,18 +173,16 @@ mod test { ) .await .expect("A client!"); - dbg!("Begin test fn 3"); let proposal = ProposalBuilder::default().build(); - dbg!("Begin test fn 4"); let step = StepBuilder::default().build(); let step_results: Vec<( &zcash_client_backend::proposal::Step, zcash_primitives::transaction::builder::BuildResult, )> = vec![]; - dbg!("Here?"); let step_result = client .update_tmamt_and_return_step_result(&proposal, step, &step_results) .await; + dbg!(step_result.unwrap()); } } From a7948a17bff4ea9033c61b7a91e33e37278b61e6 Mon Sep 17 00:00:00 2001 From: zancas Date: Wed, 8 May 2024 06:51:13 -0600 Subject: [PATCH 10/13] remove dbgs --- zingolib/src/test_framework/mocks.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/zingolib/src/test_framework/mocks.rs b/zingolib/src/test_framework/mocks.rs index 8f276a51fe..e776e505cf 100644 --- a/zingolib/src/test_framework/mocks.rs +++ b/zingolib/src/test_framework/mocks.rs @@ -324,9 +324,7 @@ pub mod proposal { /// `build` will panic if any fields of the builder are `None` or if the build failed /// due to invalid values. pub fn build(self) -> Proposal { - dbg!("Inside Proposal Builder build"); let step = self.steps.unwrap().first().clone(); - dbg!("Ooopppsss!"); Proposal::single_step( step.transaction_request().clone(), step.payment_pools().clone(), @@ -344,9 +342,7 @@ pub mod proposal { impl Default for ProposalBuilder { /// Constructs a new [`ProposalBuilder`] where all fields are preset to default values. fn default() -> Self { - dbg!("Inside ProposalBuilder default about to call new()."); let mut builder = ProposalBuilder::new(); - dbg!("Inside default about to build."); builder .fee_rule(FeeRule::standard()) .min_target_height(BlockHeight::from_u32(1)) From 7c9c0726b3bf681c39cfaf913a50f31ccaeb40bc Mon Sep 17 00:00:00 2001 From: zancas Date: Wed, 8 May 2024 06:52:35 -0600 Subject: [PATCH 11/13] remove dbgs --- zingolib/src/test_framework/mocks.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/zingolib/src/test_framework/mocks.rs b/zingolib/src/test_framework/mocks.rs index e776e505cf..6efb51c69b 100644 --- a/zingolib/src/test_framework/mocks.rs +++ b/zingolib/src/test_framework/mocks.rs @@ -401,7 +401,6 @@ pub mod proposal { /// due to invalid values. #[allow(dead_code)] pub fn build(self) -> Step { - dbg!("building!"); Step::from_parts( &[], self.transaction_request.unwrap(), From 18d448ef3da7f417cbbee7b55a14fdd735b2cd42 Mon Sep 17 00:00:00 2001 From: zancas Date: Wed, 8 May 2024 07:32:28 -0600 Subject: [PATCH 12/13] capture no-tree calculation error --- zingolib/src/lightclient/send.rs | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/zingolib/src/lightclient/send.rs b/zingolib/src/lightclient/send.rs index a4500eb61e..fe3e16004c 100644 --- a/zingolib/src/lightclient/send.rs +++ b/zingolib/src/lightclient/send.rs @@ -159,12 +159,12 @@ mod test { use zingoconfig::ZingoConfigBuilder; use crate::{ - lightclient::LightClient, + lightclient::{send::DoSendProposedError, LightClient}, test_framework::mocks::{ProposalBuilder, StepBuilder}, }; #[tokio::test] - async fn update_tmamt_and_return_step_result() { + async fn update_tmamt_and_return_step_result_no_receipts() { let config = ZingoConfigBuilder::default().create(); let client = LightClient::create_unconnected( &config, @@ -182,8 +182,30 @@ mod test { let step_result = client .update_tmamt_and_return_step_result(&proposal, step, &step_results) .await; - dbg!(step_result.unwrap()); + dbg!(&step_result); + if let Err(DoSendProposedError::Calculation(e)) = step_result { + if let zcash_client_backend::data_api::error::Error::CommitmentTree(e2) = e { + if let shardtree::error::ShardTreeError::Query(e3) = e2 { + assert_eq!(e3, shardtree::error::QueryError::CheckpointPruned); + } else { + panic!("Wrong Error in layer 3."); + }; + } else { + panic!("Wrong zcash_api error!"); + } + } else { + panic!("Wrong state!"); + } } + /* + match step_result { + Err(DoSendProposedError::Calculation(e)) => { + match e { + zcash_client_backend::data_api::error::Error::CommitmentTree(e) + } + } + _ => panic!(), + */ } /// Errors that can result from do_send_proposed From bec833d62bff7e5e768c6e2cf26258640fb2fe71 Mon Sep 17 00:00:00 2001 From: zancas Date: Wed, 8 May 2024 09:56:46 -0600 Subject: [PATCH 13/13] revert to fluidv's version --- zingolib/src/wallet/send.rs | 43 ++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/zingolib/src/wallet/send.rs b/zingolib/src/wallet/send.rs index 50a7a17673..c0f8b08f24 100644 --- a/zingolib/src/wallet/send.rs +++ b/zingolib/src/wallet/send.rs @@ -834,25 +834,6 @@ impl LightWallet { Ok(tx_builder) } - #[cfg(feature = "darkside_tests")] - async fn get_darkside_txid( - transaction: &Transaction, - broadcast_fn: F, - ) -> Result - where - F: Fn(Box<[u8]>) -> Fut, - Fut: Future>, - { - let mut raw_transaction = vec![]; - transaction.write(&mut raw_transaction).unwrap(); - let serverz_transaction_id = - broadcast_fn(raw_transaction.clone().into_boxed_slice()).await?; - if let Ok(serverz_txid_bytes) = dbg!(serverz_transaction_id).into_bytes().try_into() { - Ok(TxId::from_bytes(serverz_txid_bytes)) - } else { - Err("Couldn't transfrom string to bytes.".to_string()) - } - } pub(crate) async fn send_to_addresses_inner( &self, transaction: &Transaction, @@ -867,6 +848,13 @@ impl LightWallet { self.send_progress.write().await.is_send_in_progress = false; } + // Create the transaction bytes + let mut raw_transaction = vec![]; + transaction.write(&mut raw_transaction).unwrap(); + + let serverz_transaction_id = + broadcast_fn(raw_transaction.clone().into_boxed_slice()).await?; + // Add this transaction to the mempool structure { let price = self.price.read().await.clone(); @@ -877,11 +865,22 @@ impl LightWallet { .await; } - #[cfg(not(feature = "darkside_tests"))] let txid = transaction.txid(); - #[cfg(feature = "darkside_tests")] - let txid = LightWallet::get_darkside_txid(transaction, broadcast_fn).await?; + if let Ok(serverz_txid_bytes) = dbg!(serverz_transaction_id).into_bytes().try_into() { + let serverz_txid = TxId::from_bytes(serverz_txid_bytes); + if txid != serverz_txid { + // happens during darkside tests + dbg!( + "served txid {} does not match calulated txid {}", + serverz_txid, + txid, + ); + if self.transaction_context.config.accept_server_txids { + return Ok(serverz_txid); + } + } + } Ok(txid) }