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.
This commit is contained in:
Kris Nuttycombe 2022-10-13 20:20:46 -06:00
parent 85f69fa787
commit 69791af92c
2 changed files with 14 additions and 12 deletions

View File

@ -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<N, E, P, D>(
@ -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(())
}

View File

@ -538,7 +538,6 @@ impl<'a, P: consensus::Parameters> WalletWrite for DataConnStmtCache<'a, P> {
&mut self,
d_tx: &DecryptedTransaction,
) -> Result<Self::TxRef, Self::Error> {
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.