From 1b20142caf8fbc34630dcee10bf068f31b9811bd Mon Sep 17 00:00:00 2001 From: borngraced Date: Wed, 1 Nov 2023 15:08:49 +0100 Subject: [PATCH] fix review notes --- zcash_client_backend/Cargo.toml | 1 - zcash_client_backend/src/data_api.rs | 1 - zcash_client_backend/src/data_api/wallet.rs | 42 +++++++++++++++++++++ zcash_client_sqlite/src/for_async/mod.rs | 32 ++++++++-------- zcash_client_sqlite/src/lib.rs | 1 - zcash_extras/Cargo.toml | 4 ++ zcash_extras/src/lib.rs | 20 ++-------- 7 files changed, 67 insertions(+), 34 deletions(-) diff --git a/zcash_client_backend/Cargo.toml b/zcash_client_backend/Cargo.toml index 3616019088..7660f01f04 100644 --- a/zcash_client_backend/Cargo.toml +++ b/zcash_client_backend/Cargo.toml @@ -53,7 +53,6 @@ zcash_proofs = { version = "0.5", path = "../zcash_proofs" } [target.'cfg(target_arch = "wasm32")'.dev-dependencies] zcash_proofs = { version = "0.5", path = "../zcash_proofs", default-features = false, features = ["local-prover"]} - [features] test-dependencies = ["proptest", "zcash_primitives/test-dependencies"] diff --git a/zcash_client_backend/src/data_api.rs b/zcash_client_backend/src/data_api.rs index ef4f2fd615..166fd80cba 100644 --- a/zcash_client_backend/src/data_api.rs +++ b/zcash_client_backend/src/data_api.rs @@ -178,7 +178,6 @@ pub trait WalletRead { /// The subset of information that is relevant to this wallet that has been /// decrypted and extracted from a [CompactBlock]. -#[derive(Clone)] pub struct PrunedBlock<'a> { pub block_height: BlockHeight, pub block_hash: BlockHash, diff --git a/zcash_client_backend/src/data_api/wallet.rs b/zcash_client_backend/src/data_api/wallet.rs index 20c2a3828f..090bb14a79 100644 --- a/zcash_client_backend/src/data_api/wallet.rs +++ b/zcash_client_backend/src/data_api/wallet.rs @@ -1,6 +1,8 @@ //! Functions for scanning the chain and extracting relevant information. use std::fmt::Debug; +use zcash_primitives::consensus::NetworkUpgrade; +use zcash_primitives::transaction::Transaction; use zcash_primitives::{ consensus::{self, BranchId}, memo::MemoBytes, @@ -12,14 +14,54 @@ use zcash_primitives::{ zip32::{ExtendedFullViewingKey, ExtendedSpendingKey}, }; +use crate::data_api::ReceivedTransaction; use crate::{ address::RecipientAddress, data_api::{error::Error, SentTransaction, WalletWrite}, + decrypt_transaction, wallet::{AccountId, OvkPolicy}, }; pub const ANCHOR_OFFSET: u32 = 10; +/// Scans a [`Transaction`] for any information that can be decrypted by the accounts in +/// the wallet, and saves it to the wallet. +pub fn decrypt_and_store_transaction( + params: &P, + data: &mut D, + tx: &Transaction, +) -> Result<(), E> +where + E: From>, + P: consensus::Parameters, + D: WalletWrite, +{ + // Fetch the ExtendedFullViewingKeys we are tracking + let extfvks = data.get_extended_full_viewing_keys()?; + + // Height is block height for mined transactions, and the "mempool height" (chain height + 1) + // for mempool transactions. + let height = data + .get_tx_height(tx.txid())? + .or(data + .block_height_extrema()? + .map(|(_, max_height)| max_height + 1)) + .or_else(|| params.activation_height(NetworkUpgrade::Sapling)) + .ok_or(Error::SaplingNotActive)?; + + let outputs = decrypt_transaction(params, height, tx, &extfvks); + if outputs.is_empty() { + Ok(()) + } else { + data.store_received_tx(&ReceivedTransaction { + tx, + outputs: &outputs, + })?; + + Ok(()) + } +} + #[allow(clippy::needless_doctest_main)] /// Creates a transaction paying the specified address from the given account. /// diff --git a/zcash_client_sqlite/src/for_async/mod.rs b/zcash_client_sqlite/src/for_async/mod.rs index 810ca6c244..ebe60393a0 100644 --- a/zcash_client_sqlite/src/for_async/mod.rs +++ b/zcash_client_sqlite/src/for_async/mod.rs @@ -4,6 +4,7 @@ pub mod wallet_actions; use std::collections::HashMap; use std::path::Path; use tokio::task::block_in_place; +use zcash_client_backend::data_api::WalletWrite as WalletWriteSync; use zcash_client_backend::data_api::{PrunedBlock, ReceivedTransaction, SentTransaction}; use zcash_client_backend::wallet::{AccountId, SpendableNote}; use zcash_extras::{WalletRead, WalletWrite}; @@ -330,36 +331,37 @@ impl WalletWrite for DataConnS block: &PrunedBlock, updated_witnesses: &[(Self::NoteRef, IncrementalWitness)], ) -> Result)>, Self::Error> { - use zcash_client_backend::data_api::WalletWrite; - // database updates for each block are transactional - let db = self.wallet_db.inner.lock().unwrap(); - let mut update_ops = db.get_update_ops()?; - block_in_place(|| update_ops.advance_by_block(&block, updated_witnesses)) + block_in_place(|| { + let db = self.wallet_db.inner.lock().unwrap(); + let mut update_ops = db.get_update_ops()?; + update_ops.advance_by_block(&block, updated_witnesses) + }) } async fn store_received_tx( &mut self, received_tx: &ReceivedTransaction, ) -> Result { - use zcash_client_backend::data_api::WalletWrite; - // database updates for each block are transactional - let db = self.wallet_db.inner.lock().unwrap(); - let mut update_ops = db.get_update_ops()?; - block_in_place(|| update_ops.store_received_tx(&received_tx)) + block_in_place(|| { + let db = self.wallet_db.inner.lock().unwrap(); + let mut update_ops = db.get_update_ops()?; + update_ops.store_received_tx(&received_tx) + }) } async fn store_sent_tx( &mut self, sent_tx: &SentTransaction, ) -> Result { - use zcash_client_backend::data_api::WalletWrite; - // Update the database atomically, to ensure the result is internally consistent. - let db = self.wallet_db.inner.lock().unwrap(); - let mut update_ops = db.get_update_ops()?; - block_in_place(|| update_ops.store_sent_tx(&sent_tx)) + + block_in_place(|| { + let db = self.wallet_db.inner.lock().unwrap(); + let mut update_ops = db.get_update_ops()?; + update_ops.store_sent_tx(&sent_tx) + }) } async fn rewind_to_height(&mut self, block_height: BlockHeight) -> Result<(), Self::Error> { diff --git a/zcash_client_sqlite/src/lib.rs b/zcash_client_sqlite/src/lib.rs index 157374423e..91561417eb 100644 --- a/zcash_client_sqlite/src/lib.rs +++ b/zcash_client_sqlite/src/lib.rs @@ -35,7 +35,6 @@ extern crate core; use std::collections::HashMap; -//use std::fmt; use std::path::Path; use rusqlite::{Connection, Statement}; diff --git a/zcash_extras/Cargo.toml b/zcash_extras/Cargo.toml index 109f24541a..aa07c7ca88 100644 --- a/zcash_extras/Cargo.toml +++ b/zcash_extras/Cargo.toml @@ -3,6 +3,9 @@ name = "zcash_extras" version = "0.1.0" edition = "2018" +[lib] +doctest = false + [dependencies] async-trait = "0.1.52" group = "0.8" @@ -18,3 +21,4 @@ time = "0.3.20" [target.'cfg(target_arch = "wasm32")'.dependencies] time = { version = "0.3.20", features = ["wasm-bindgen"]} + diff --git a/zcash_extras/src/lib.rs b/zcash_extras/src/lib.rs index 3470697818..73f357b619 100644 --- a/zcash_extras/src/lib.rs +++ b/zcash_extras/src/lib.rs @@ -280,23 +280,11 @@ impl fmt::Display for NoteId { } } } -#[cfg(feature = "mainnet")] -pub(crate) fn network() -> Network { - Network::MainNetwork -} -#[cfg(not(feature = "mainnet"))] -pub(crate) fn network() -> Network { +pub(crate) fn test_network() -> Network { Network::TestNetwork } -#[cfg(feature = "mainnet")] -pub(crate) fn sapling_activation_height() -> BlockHeight { - Network::MainNetwork - .activation_height(NetworkUpgrade::Sapling) - .unwrap() -} - /// Create a fake CompactBlock at the given height, containing a single output paying /// the given address. Returns the CompactBlock and the nullifier for the new note. pub fn fake_compact_block( @@ -309,7 +297,7 @@ pub fn fake_compact_block( // Create a fake Note for the account let mut rng = OsRng; - let rseed = generate_random_rseed(&network(), height, &mut rng); + let rseed = generate_random_rseed(&test_network(), height, &mut rng); let note = Note { g_d: to.diversifier().g_d().unwrap(), pk_d: *to.pk_d(), @@ -357,7 +345,7 @@ pub fn fake_compact_block_spending( value: Amount, ) -> CompactBlock { let mut rng = OsRng; - let rseed = generate_random_rseed(&network(), height, &mut rng); + let rseed = generate_random_rseed(&test_network(), height, &mut rng); // Create a fake CompactBlock containing the note let mut cspend = CompactSpend::new(); @@ -397,7 +385,7 @@ pub fn fake_compact_block_spending( // Create a fake Note for the change ctx.outputs.push({ let change_addr = extfvk.default_address().unwrap().1; - let rseed = generate_random_rseed(&network(), height, &mut rng); + let rseed = generate_random_rseed(&test_network(), height, &mut rng); let note = Note { g_d: change_addr.diversifier().g_d().unwrap(), pk_d: *change_addr.pk_d(),