Allow shielding from multiple taddrs within a single transaction.

This commit is contained in:
Kris Nuttycombe 2022-10-25 12:26:02 -06:00
parent efa95fcb39
commit 334383f363
2 changed files with 27 additions and 22 deletions

View File

@ -23,7 +23,10 @@ use crate::{
};
#[cfg(feature = "transparent-inputs")]
use zcash_primitives::{legacy::TransparentAddress, sapling::keys::OutgoingViewingKey};
use {
crate::wallet::WalletTransparentOutput,
zcash_primitives::{legacy::TransparentAddress, 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.
@ -440,7 +443,7 @@ pub fn shield_transparent_funds<E, N, P, D, R, U>(
params: &P,
prover: impl TxProver,
usk: &UnifiedSpendingKey,
from_addr: &TransparentAddress,
from_addrs: &[TransparentAddress],
memo: &MemoBytes,
min_confirmations: u32,
) -> Result<D::TxRef, E>
@ -466,8 +469,13 @@ where
let account_pubkey = usk.transparent().to_account_pubkey();
let ovk = OutgoingViewingKey(account_pubkey.internal_ovk().as_bytes());
// get UTXOs from DB
let utxos = wallet_db.get_unspent_transparent_outputs(from_addr, latest_anchor)?;
// get UTXOs from DB for each address
let mut utxos: Vec<WalletTransparentOutput> = vec![];
for from_addr in from_addrs {
let mut outputs = wallet_db.get_unspent_transparent_outputs(from_addr, latest_anchor)?;
utxos.append(&mut outputs);
}
let total_amount = utxos
.iter()
.map(|utxo| utxo.txout().value)
@ -481,23 +489,22 @@ where
let amount_to_shield = (total_amount - fee).ok_or_else(|| E::from(Error::InvalidAmount))?;
let addr_metadata = wallet_db.get_transparent_receivers(account)?;
let mut builder = Builder::new_with_fee(params.clone(), latest_scanned_height, fee);
let diversifier_index = *wallet_db
.get_transparent_receivers(account)?
.get(from_addr)
.ok_or(Error::AddressNotRecognized(*from_addr))?
.diversifier_index();
let child_index = u32::try_from(diversifier_index)
.map_err(|_| Error::ChildIndexOutOfRange(diversifier_index))?;
let secret_key = usk
.transparent()
.derive_external_secret_key(child_index)
.unwrap();
for utxo in &utxos {
let diversifier_index = addr_metadata
.get(utxo.recipient_address())
.ok_or_else(|| Error::AddressNotRecognized(*utxo.recipient_address()))?
.diversifier_index();
let child_index = u32::try_from(*diversifier_index)
.map_err(|_| Error::ChildIndexOutOfRange(*diversifier_index))?;
let secret_key = usk
.transparent()
.derive_external_secret_key(child_index)
.unwrap();
builder
.add_transparent_input(secret_key, utxo.outpoint().clone(), utxo.txout().clone())
.map_err(Error::Builder)?;

View File

@ -236,9 +236,7 @@ pub(crate) fn get_current_address<P: consensus::Parameters>(
addr.map(|(addr_str, di_vec)| {
let mut di_be: [u8; 11] = di_vec.try_into().map_err(|_| {
SqliteClientError::CorruptedData(
"Diversifier index is not an 11-byte value".to_owned(),
)
SqliteClientError::CorruptedData("Diversifier index is not an 11-byte value".to_owned())
})?;
di_be.reverse();