Ensure that Sapling padding outputs are taken account in ZIP 317 change computation.

Fixes #799
This commit is contained in:
Kris Nuttycombe 2023-04-05 18:33:14 -06:00
parent 3e54e1def1
commit f1f63043ca
1 changed files with 34 additions and 1 deletions

View File

@ -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::<TestTransparentInput>::new(),
&[TxOut {
value: Amount::from_u64(40000).unwrap(),
script_pubkey: Script(vec![]),
}],
&[TestSaplingInput {
note_id: 0,
value: Amount::from_u64(55000).unwrap(),
}],
&Vec::<SaplingPayment>::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());