From f1f63043ca4d4a97936f5a8b3bc7490af92bbb34 Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Wed, 5 Apr 2023 18:33:14 -0600 Subject: [PATCH] Ensure that Sapling padding outputs are taken account in ZIP 317 change computation. Fixes #799 --- zcash_client_backend/src/fees/zip317.rs | 35 ++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/zcash_client_backend/src/fees/zip317.rs b/zcash_client_backend/src/fees/zip317.rs index 174671eb1..142bf7ce6 100644 --- a/zcash_client_backend/src/fees/zip317.rs +++ b/zcash_client_backend/src/fees/zip317.rs @@ -164,7 +164,9 @@ impl ChangeStrategy for SingleOutputChangeStrategy { transparent_inputs, transparent_outputs, sapling_inputs.len(), - sapling_outputs.len() + 1, + // add one for Sapling change, then account for Sapling output padding performed by + // the transaction builder + std::cmp::max(sapling_outputs.len() + 1, 2), ) .map_err(ChangeError::StrategyError)?; @@ -222,6 +224,7 @@ mod tests { use zcash_primitives::{ consensus::{Network, NetworkUpgrade, Parameters}, + legacy::Script, transaction::{ components::{amount::Amount, transparent::TxOut}, fees::zip317::FeeRule as Zip317FeeRule, @@ -264,6 +267,36 @@ mod tests { ); } + #[test] + fn change_with_transparent_payments() { + let change_strategy = SingleOutputChangeStrategy::new(Zip317FeeRule::standard()); + + // spend a single Sapling note that is sufficient to pay the fee + let result = change_strategy.compute_balance( + &Network::TestNetwork, + Network::TestNetwork + .activation_height(NetworkUpgrade::Nu5) + .unwrap(), + &Vec::::new(), + &[TxOut { + value: Amount::from_u64(40000).unwrap(), + script_pubkey: Script(vec![]), + }], + &[TestSaplingInput { + note_id: 0, + value: Amount::from_u64(55000).unwrap(), + }], + &Vec::::new(), + &DustOutputPolicy::default(), + ); + + assert_matches!( + result, + Ok(balance) if balance.proposed_change().is_empty() + && balance.fee_required() == Amount::from_u64(15000).unwrap() + ); + } + #[test] fn change_with_allowable_dust() { let change_strategy = SingleOutputChangeStrategy::new(Zip317FeeRule::standard());