From 69791af92cc5ac55870dac5f2028aedff471b32a Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Thu, 13 Oct 2022 20:20:46 -0600 Subject: [PATCH] Mark our utxos spent when we detect them as inputs to a transaction. This modifies `decrypt_and_store_transaction` to check for inputs to a transaction being decrypted that correspond to utxos known to our wallet. For each such UTXO found, it is marked spent. --- zcash_client_backend/src/data_api/wallet.rs | 18 +++++++----------- zcash_client_sqlite/src/lib.rs | 8 +++++++- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/zcash_client_backend/src/data_api/wallet.rs b/zcash_client_backend/src/data_api/wallet.rs index 226fa85b7..4c1ab4312 100644 --- a/zcash_client_backend/src/data_api/wallet.rs +++ b/zcash_client_backend/src/data_api/wallet.rs @@ -10,9 +10,6 @@ use zcash_primitives::{ }, }; -#[cfg(feature = "transparent-inputs")] -use zcash_primitives::{legacy::keys::IncomingViewingKey, sapling::keys::OutgoingViewingKey}; - use crate::{ address::RecipientAddress, data_api::{ @@ -25,6 +22,9 @@ use crate::{ zip321::{Payment, TransactionRequest}, }; +#[cfg(feature = "transparent-inputs")] +use zcash_primitives::{legacy::keys::IncomingViewingKey, sapling::keys::OutgoingViewingKey}; + /// 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( @@ -50,14 +50,10 @@ where .or_else(|| params.activation_height(NetworkUpgrade::Sapling)) .ok_or(Error::SaplingNotActive)?; - let sapling_outputs = decrypt_transaction(params, height, tx, &ufvks); - - if !(sapling_outputs.is_empty() && tx.transparent_bundle().iter().all(|b| b.vout.is_empty())) { - data.store_decrypted_tx(&DecryptedTransaction { - tx, - sapling_outputs: &sapling_outputs, - })?; - } + data.store_decrypted_tx(&DecryptedTransaction { + tx, + sapling_outputs: &decrypt_transaction(params, height, tx, &ufvks), + })?; Ok(()) } diff --git a/zcash_client_sqlite/src/lib.rs b/zcash_client_sqlite/src/lib.rs index 21369bb95..afb75c73f 100644 --- a/zcash_client_sqlite/src/lib.rs +++ b/zcash_client_sqlite/src/lib.rs @@ -538,7 +538,6 @@ impl<'a, P: consensus::Parameters> WalletWrite for DataConnStmtCache<'a, P> { &mut self, d_tx: &DecryptedTransaction, ) -> Result { - let nullifiers = self.wallet_db.get_all_nullifiers()?; self.transactionally(|up| { let tx_ref = wallet::put_tx_data(up, d_tx.tx, None, None)?; @@ -579,8 +578,15 @@ impl<'a, P: consensus::Parameters> WalletWrite for DataConnStmtCache<'a, P> { } } + // If any of the utxos spent in the transaction are ours, mark them as spent. + #[cfg(feature = "transparent-inputs")] + for txin in d_tx.tx.transparent_bundle().iter().flat_map(|b| b.vin.iter()) { + wallet::mark_transparent_utxo_spent(up, tx_ref, &txin.prevout)?; + } + // If we have some transparent outputs: if !d_tx.tx.transparent_bundle().iter().any(|b| b.vout.is_empty()) { + let nullifiers = self.wallet_db.get_all_nullifiers()?; // If the transaction contains shielded spends from our wallet, we will store z->t // transactions we observe in the same way they would be stored by // create_spend_to_address.