diff --git a/zcash_client_backend/src/fees/fixed.rs b/zcash_client_backend/src/fees/fixed.rs index d57953399..eea1f1602 100644 --- a/zcash_client_backend/src/fees/fixed.rs +++ b/zcash_client_backend/src/fees/fixed.rs @@ -185,7 +185,7 @@ mod tests { &Vec::::new(), &[TestSaplingInput { note_id: 0, - value: Amount::from_u64(45000).unwrap(), + value: Amount::from_u64(60000).unwrap(), }], &[SaplingPayment::new(Amount::from_u64(40000).unwrap())], &DustOutputPolicy::default(), @@ -193,8 +193,8 @@ mod tests { assert_matches!( result, - Ok(balance) if balance.proposed_change() == [ChangeValue::Sapling(Amount::from_u64(4000).unwrap())] - && balance.fee_required() == Amount::from_u64(1000).unwrap() + Ok(balance) if balance.proposed_change() == [ChangeValue::Sapling(Amount::from_u64(10000).unwrap())] + && balance.fee_required() == Amount::from_u64(10000).unwrap() ); } @@ -218,7 +218,7 @@ mod tests { // enough to pay a fee, plus dust TestSaplingInput { note_id: 0, - value: Amount::from_u64(1100).unwrap(), + value: Amount::from_u64(10100).unwrap(), }, ], &[SaplingPayment::new(Amount::from_u64(40000).unwrap())], @@ -228,7 +228,7 @@ mod tests { assert_matches!( result, Err(ChangeError::InsufficientFunds { available, required }) - if available == Amount::from_u64(41100).unwrap() && required == Amount::from_u64(42000).unwrap() + if available == Amount::from_u64(50100).unwrap() && required == Amount::from_u64(60000).unwrap() ); } } diff --git a/zcash_client_sqlite/src/wallet/transact.rs b/zcash_client_sqlite/src/wallet/transact.rs index 613749c68..a165174ce 100644 --- a/zcash_client_sqlite/src/wallet/transact.rs +++ b/zcash_client_sqlite/src/wallet/transact.rs @@ -354,7 +354,7 @@ mod tests { available, required }) - if available == Amount::zero() && required == Amount::from_u64(1001).unwrap() + if available == Amount::zero() && required == Amount::from_u64(10001).unwrap() ); } @@ -437,7 +437,7 @@ mod tests { required }) if available == Amount::from_u64(50000).unwrap() - && required == Amount::from_u64(71000).unwrap() + && required == Amount::from_u64(80000).unwrap() ); // Mine blocks SAPLING_ACTIVATION_HEIGHT + 2 to 9 until just before the second @@ -472,7 +472,7 @@ mod tests { required }) if available == Amount::from_u64(50000).unwrap() - && required == Amount::from_u64(71000).unwrap() + && required == Amount::from_u64(80000).unwrap() ); // Mine block 11 so that the second note becomes verified @@ -568,7 +568,7 @@ mod tests { available, required }) - if available == Amount::zero() && required == Amount::from_u64(3000).unwrap() + if available == Amount::zero() && required == Amount::from_u64(12000).unwrap() ); // Mine blocks SAPLING_ACTIVATION_HEIGHT + 1 to 21 (that don't send us funds) @@ -602,7 +602,7 @@ mod tests { available, required }) - if available == Amount::zero() && required == Amount::from_u64(3000).unwrap() + if available == Amount::zero() && required == Amount::from_u64(12000).unwrap() ); // Mine block SAPLING_ACTIVATION_HEIGHT + 22 so that the first transaction expires @@ -752,7 +752,7 @@ mod tests { let dfvk = usk.sapling().to_diversifiable_full_viewing_key(); // Add funds to the wallet in a single note - let value = Amount::from_u64(51000).unwrap(); + let value = Amount::from_u64(60000).unwrap(); let (cb, _) = fake_compact_block( sapling_activation_height(), BlockHash([0; 32]), @@ -806,7 +806,7 @@ mod tests { let dfvk = usk.sapling().to_diversifiable_full_viewing_key(); // Add funds to the wallet in a single note - let value = Amount::from_u64(51000).unwrap(); + let value = Amount::from_u64(60000).unwrap(); let (cb, _) = fake_compact_block( sapling_activation_height(), BlockHash([0; 32]), diff --git a/zcash_extensions/src/transparent/demo.rs b/zcash_extensions/src/transparent/demo.rs index 2bd998262..942168bb0 100644 --- a/zcash_extensions/src/transparent/demo.rs +++ b/zcash_extensions/src/transparent/demo.rs @@ -812,7 +812,7 @@ mod tests { // create some inputs to spend let extsk = ExtendedSpendingKey::master(&[]); let to = extsk.default_address().1; - let note1 = to.create_note(101000, Rseed::BeforeZip212(jubjub::Fr::random(&mut rng))); + let note1 = to.create_note(110000, Rseed::BeforeZip212(jubjub::Fr::random(&mut rng))); let cm1 = Node::from_cmu(¬e1.cmu()); let mut tree = sapling::CommitmentTree::empty(); // fake that the note appears in some previous diff --git a/zcash_primitives/CHANGELOG.md b/zcash_primitives/CHANGELOG.md index 53a8539fd..1a0c0c57b 100644 --- a/zcash_primitives/CHANGELOG.md +++ b/zcash_primitives/CHANGELOG.md @@ -78,6 +78,9 @@ and this library adheres to Rust's notion of - `merkle_tree::incremental::read_auth_fragment_v1` - The depth of the `merkle_tree::{CommitmentTree, IncrementalWitness, and MerklePath}` data types are now statically constrained using const generic type parameters. +- `transaction::fees::fixed::FeeRule::standard()` now uses the ZIP 317 minimum fee + (10000 zatoshis rather than 1000 zatoshis) as the fixed fee. To be compliant with + ZIP 317, use `transaction::fees::zip317::FeeRule::standard()` instead. ## [0.11.0] - 2023-04-15 ### Added diff --git a/zcash_primitives/src/transaction/builder.rs b/zcash_primitives/src/transaction/builder.rs index 1f51ed8e7..ecb11d2e2 100644 --- a/zcash_primitives/src/transaction/builder.rs +++ b/zcash_primitives/src/transaction/builder.rs @@ -550,7 +550,7 @@ mod tests { memo::MemoBytes, sapling::{Node, Rseed}, transaction::components::{ - amount::{Amount, DEFAULT_FEE}, + amount::Amount, sapling::builder::{self as sapling_builder}, transparent::builder::{self as transparent_builder}, }, @@ -646,7 +646,7 @@ mod tests { builder .add_transparent_output( &TransparentAddress::PublicKey([0; 20]), - Amount::from_u64(49000).unwrap(), + Amount::from_u64(40000).unwrap(), ) .unwrap(); @@ -682,7 +682,7 @@ mod tests { builder .add_transparent_output( &TransparentAddress::PublicKey([0; 20]), - Amount::from_u64(49000).unwrap(), + Amount::from_u64(40000).unwrap(), ) .unwrap(); @@ -711,6 +711,8 @@ mod tests { #[test] fn fails_on_negative_change() { + use crate::transaction::fees::zip317::MINIMUM_FEE; + let mut rng = OsRng; // Just use the master key as the ExtendedSpendingKey for this test @@ -725,7 +727,7 @@ mod tests { let builder = Builder::new(TEST_NETWORK, tx_height); assert_eq!( builder.mock_build(), - Err(Error::InsufficientFunds(DEFAULT_FEE)) + Err(Error::InsufficientFunds(MINIMUM_FEE)) ); } @@ -734,7 +736,7 @@ mod tests { let to = dfvk.default_address().1; // Fail if there is only a Sapling output - // 0.0005 z-ZEC out, 0.00001 t-ZEC fee + // 0.0005 z-ZEC out, 0.0001 t-ZEC fee { let mut builder = Builder::new(TEST_NETWORK, tx_height); builder @@ -748,13 +750,13 @@ mod tests { assert_eq!( builder.mock_build(), Err(Error::InsufficientFunds( - (Amount::from_i64(50000).unwrap() + DEFAULT_FEE).unwrap() + (Amount::from_i64(50000).unwrap() + MINIMUM_FEE).unwrap() )) ); } // Fail if there is only a transparent output - // 0.0005 t-ZEC out, 0.00001 t-ZEC fee + // 0.0005 t-ZEC out, 0.0001 t-ZEC fee { let mut builder = Builder::new(TEST_NETWORK, tx_height); builder @@ -766,19 +768,19 @@ mod tests { assert_eq!( builder.mock_build(), Err(Error::InsufficientFunds( - (Amount::from_i64(50000).unwrap() + DEFAULT_FEE).unwrap() + (Amount::from_i64(50000).unwrap() + MINIMUM_FEE).unwrap() )) ); } - let note1 = to.create_note(50999, Rseed::BeforeZip212(jubjub::Fr::random(&mut rng))); + let note1 = to.create_note(59999, Rseed::BeforeZip212(jubjub::Fr::random(&mut rng))); let cmu1 = Node::from_cmu(¬e1.cmu()); let mut tree = CommitmentTree::::empty(); tree.append(cmu1).unwrap(); let mut witness1 = IncrementalWitness::from_tree(tree.clone()); // Fail if there is insufficient input - // 0.0003 z-ZEC out, 0.0002 t-ZEC out, 0.00001 t-ZEC fee, 0.00050999 z-ZEC in + // 0.0003 z-ZEC out, 0.0002 t-ZEC out, 0.0001 t-ZEC fee, 0.00059999 z-ZEC in { let mut builder = Builder::new(TEST_NETWORK, tx_height); builder diff --git a/zcash_primitives/src/transaction/fees/fixed.rs b/zcash_primitives/src/transaction/fees/fixed.rs index e9dfd7613..38e365d17 100644 --- a/zcash_primitives/src/transaction/fees/fixed.rs +++ b/zcash_primitives/src/transaction/fees/fixed.rs @@ -1,9 +1,7 @@ use crate::{ consensus::{self, BlockHeight}, - transaction::components::{ - amount::{Amount, DEFAULT_FEE}, - transparent::fees as transparent, - }, + transaction::components::{amount::Amount, transparent::fees as transparent}, + transaction::fees::zip317, }; #[cfg(feature = "zfuture")] @@ -22,10 +20,17 @@ impl FeeRule { Self { fixed_fee } } - /// Creates a new fixed fee rule with the standard default fee. + /// Creates a new fixed fee rule with the minimum possible [ZIP 317] fee, + /// i.e. 10000 zatoshis. + /// + /// Note that using a fixed fee is not compliant with [ZIP 317]; consider + /// using [`zcash_primitives::transaction::fees::zip317::FeeRule`] instead. + /// + /// [`zcash_primitives::transaction::fees::zip317::FeeRule`]: crate::transaction::fees::zip317::FeeRule + /// [ZIP 317]: https://zips.z.cash/zip-0317 pub fn standard() -> Self { Self { - fixed_fee: DEFAULT_FEE, + fixed_fee: zip317::MINIMUM_FEE, } }