From 0f56f095c278ceb7cd62921ded8d8edf32f031c2 Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Thu, 8 Dec 2022 17:15:48 -0700 Subject: [PATCH] Add `shielding_threshold` argument to `shield_transparent_funds`. Previously, the shielding threshold was fixed to 100000 zatoshis. Fixes #726 --- zcash_client_backend/CHANGELOG.md | 10 +++ zcash_client_backend/src/data_api/wallet.rs | 3 +- zcash_client_sqlite/src/wallet/transact.rs | 79 +++++++++++++++++++ .../components/transparent/builder.rs | 2 +- 4 files changed, 92 insertions(+), 2 deletions(-) diff --git a/zcash_client_backend/CHANGELOG.md b/zcash_client_backend/CHANGELOG.md index e6909948b..e13e5c56b 100644 --- a/zcash_client_backend/CHANGELOG.md +++ b/zcash_client_backend/CHANGELOG.md @@ -7,6 +7,16 @@ and this library adheres to Rust's notion of ## [Unreleased] +### Changed +- `zcash_client_backend::data_api::wallet::shield_transparent_funds` now + takes a `shielding_threshold` argument that can be used to specify the + minimum value allowed as input to a shielding transaction. Previously + the shielding threshold was fixed at 100000 zatoshis. + +### Fixed +- An error that could occur when querying the transparent balance when the + wallet database contains no transparent UTXOs has been fixed. + ## [0.6.1] - 2022-12-06 ### Added - `zcash_client_backend::data_api::chain::scan_cached_blocks` now generates diff --git a/zcash_client_backend/src/data_api/wallet.rs b/zcash_client_backend/src/data_api/wallet.rs index a280bbc7f..638f00a2f 100644 --- a/zcash_client_backend/src/data_api/wallet.rs +++ b/zcash_client_backend/src/data_api/wallet.rs @@ -471,6 +471,7 @@ pub fn shield_transparent_funds( params: &ParamsT, prover: impl SaplingProver, input_selector: &InputsT, + shielding_threshold: NonNegativeAmount, usk: &UnifiedSpendingKey, from_addrs: &[TransparentAddress], memo: &MemoBytes, @@ -508,7 +509,7 @@ where let proposal = input_selector.propose_shielding( params, wallet_db, - NonNegativeAmount::from_u64(100000).unwrap(), + shielding_threshold, from_addrs, latest_anchor, target_height, diff --git a/zcash_client_sqlite/src/wallet/transact.rs b/zcash_client_sqlite/src/wallet/transact.rs index 23e87c5de..f3d017192 100644 --- a/zcash_client_sqlite/src/wallet/transact.rs +++ b/zcash_client_sqlite/src/wallet/transact.rs @@ -225,6 +225,21 @@ mod tests { AccountId, BlockDb, DataConnStmtCache, WalletDb, }; + #[cfg(feature = "transparent-inputs")] + use { + zcash_client_backend::{ + data_api::wallet::shield_transparent_funds, fees::fixed, + wallet::WalletTransparentOutput, + }, + zcash_primitives::{ + memo::MemoBytes, + transaction::{ + components::{amount::NonNegativeAmount, OutPoint, TxOut}, + fees::fixed::FeeRule as FixedFeeRule, + }, + }, + }; + fn test_prover() -> impl TxProver { match LocalTxProver::with_default_location() { Some(tx_prover) => tx_prover, @@ -947,4 +962,68 @@ mod tests { Ok(_) ); } + + #[test] + #[cfg(feature = "transparent-inputs")] + fn shield_transparent() { + let cache_file = NamedTempFile::new().unwrap(); + let db_cache = BlockDb(Connection::open(cache_file.path()).unwrap()); + init_cache_database(&db_cache).unwrap(); + + let data_file = NamedTempFile::new().unwrap(); + let mut db_data = WalletDb::for_path(data_file.path(), tests::network()).unwrap(); + init_wallet_db(&mut db_data, None).unwrap(); + + // Add an account to the wallet + let mut db_write = db_data.get_update_ops().unwrap(); + let seed = Secret::new([0u8; 32].to_vec()); + let (account_id, usk) = db_write.create_account(&seed).unwrap(); + let dfvk = usk.sapling().to_diversifiable_full_viewing_key(); + let uaddr = db_data.get_current_address(account_id).unwrap().unwrap(); + let taddr = uaddr.transparent().unwrap(); + + let utxo = WalletTransparentOutput::from_parts( + OutPoint::new([1u8; 32], 1), + TxOut { + value: Amount::from_u64(10000).unwrap(), + script_pubkey: taddr.script(), + }, + sapling_activation_height(), + ) + .unwrap(); + + let res0 = db_write.put_received_transparent_utxo(&utxo); + assert!(matches!(res0, Ok(_))); + + let input_selector = GreedyInputSelector::new( + fixed::SingleOutputChangeStrategy::new(FixedFeeRule::standard()), + DustOutputPolicy::default(), + ); + + // Add funds to the wallet + let (cb, _) = fake_compact_block( + sapling_activation_height(), + BlockHash([0; 32]), + &dfvk, + AddressType::Internal, + Amount::from_u64(50000).unwrap(), + ); + insert_into_cache(&db_cache, &cb); + scan_cached_blocks(&tests::network(), &db_cache, &mut db_write, None).unwrap(); + + assert_matches!( + shield_transparent_funds( + &mut db_write, + &tests::network(), + test_prover(), + &input_selector, + NonNegativeAmount::from_u64(10000).unwrap(), + &usk, + &[*taddr], + &MemoBytes::empty(), + 0 + ), + Ok(_) + ); + } } diff --git a/zcash_primitives/src/transaction/components/transparent/builder.rs b/zcash_primitives/src/transaction/components/transparent/builder.rs index e32398072..b812bd2f3 100644 --- a/zcash_primitives/src/transaction/components/transparent/builder.rs +++ b/zcash_primitives/src/transaction/components/transparent/builder.rs @@ -116,7 +116,7 @@ impl TransparentBuilder { #[cfg(not(feature = "transparent-inputs"))] { let invalid: &[InvalidTransparentInput] = &[]; - return invalid; + invalid } }