backend-lib: Migrate to `standard::SingleOutputChangeStrategy`

This removes the type system separation between pre-ZIP 313 and ZIP 317
fees, which becomes necessary when using the transaction proposal
protobuf encoder.
This commit is contained in:
Jack Grigg 2024-01-08 17:56:25 +00:00 committed by str4d
parent 85af183cee
commit c6c2a1c54e
1 changed files with 41 additions and 99 deletions

View File

@ -31,7 +31,7 @@ use zcash_client_backend::{
WalletSummary, WalletWrite, WalletSummary, WalletWrite,
}, },
encoding::AddressCodec, encoding::AddressCodec,
fees::DustOutputPolicy, fees::{standard::SingleOutputChangeStrategy, DustOutputPolicy},
keys::{DecodingError, Era, UnifiedAddressRequest, UnifiedFullViewingKey, UnifiedSpendingKey}, keys::{DecodingError, Era, UnifiedAddressRequest, UnifiedFullViewingKey, UnifiedSpendingKey},
proto::service::TreeState, proto::service::TreeState,
wallet::{NoteId, OvkPolicy, WalletTransparentOutput}, wallet::{NoteId, OvkPolicy, WalletTransparentOutput},
@ -55,6 +55,7 @@ use zcash_primitives::{
merkle_tree::HashSer, merkle_tree::HashSer,
transaction::{ transaction::{
components::{amount::NonNegativeAmount, Amount, OutPoint, TxOut}, components::{amount::NonNegativeAmount, Amount, OutPoint, TxOut},
fees::StandardFeeRule,
Transaction, TxId, Transaction, TxId,
}, },
zip32::{AccountId, DiversifierIndex}, zip32::{AccountId, DiversifierIndex},
@ -65,16 +66,6 @@ use crate::utils::exception::unwrap_exc_or;
mod utils; mod utils;
// Combine imports into common namespaces.
mod fixed {
pub(super) use zcash_client_backend::fees::fixed::*;
pub(super) use zcash_primitives::transaction::fees::fixed::*;
}
mod zip317 {
pub(super) use zcash_client_backend::fees::zip317::*;
pub(super) use zcash_primitives::transaction::fees::zip317::*;
}
const ANCHOR_OFFSET_U32: u32 = 10; const ANCHOR_OFFSET_U32: u32 = 10;
const ANCHOR_OFFSET: NonZeroU32 = unsafe { NonZeroU32::new_unchecked(ANCHOR_OFFSET_U32) }; const ANCHOR_OFFSET: NonZeroU32 = unsafe { NonZeroU32::new_unchecked(ANCHOR_OFFSET_U32) };
@ -1326,31 +1317,20 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_internal_jni_RustBackend_de
unwrap_exc_or(&env, res, JNI_FALSE) unwrap_exc_or(&env, res, JNI_FALSE)
} }
fn zip317_helper<Ctx, DbT, R>( fn zip317_helper<DbT>(
context: Ctx,
change_memo: Option<MemoBytes>, change_memo: Option<MemoBytes>,
use_zip317_fees: jboolean, use_zip317_fees: jboolean,
enabled: impl FnOnce(Ctx, GreedyInputSelector<DbT, zip317::SingleOutputChangeStrategy>) -> R, ) -> GreedyInputSelector<DbT, SingleOutputChangeStrategy> {
disabled: impl FnOnce(Ctx, GreedyInputSelector<DbT, fixed::SingleOutputChangeStrategy>) -> R, let fee_rule = if use_zip317_fees == JNI_TRUE {
) -> R { StandardFeeRule::Zip317
if use_zip317_fees == JNI_TRUE {
let input_selector = GreedyInputSelector::new(
zip317::SingleOutputChangeStrategy::new(zip317::FeeRule::standard(), change_memo),
DustOutputPolicy::default(),
);
enabled(context, input_selector)
} else { } else {
let input_selector = GreedyInputSelector::new( #[allow(deprecated)]
fixed::SingleOutputChangeStrategy::new( StandardFeeRule::PreZip313
fixed::FeeRule::non_standard(zip317::MINIMUM_FEE), };
change_memo, GreedyInputSelector::new(
), SingleOutputChangeStrategy::new(fee_rule, change_memo),
DustOutputPolicy::default(), DustOutputPolicy::default(),
); )
disabled(context, input_selector)
}
} }
#[no_mangle] #[no_mangle]
@ -1395,6 +1375,8 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_internal_jni_RustBackend_cr
Address::Transparent(_) => None, Address::Transparent(_) => None,
}; };
let input_selector = zip317_helper(None, use_zip317_fees);
let prover = LocalTxProver::new(Path::new(&spend_params), Path::new(&output_params)); let prover = LocalTxProver::new(Path::new(&spend_params), Path::new(&output_params));
let request = TransactionRequest::new(vec![Payment { let request = TransactionRequest::new(vec![Payment {
@ -1407,39 +1389,18 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_internal_jni_RustBackend_cr
}]) }])
.map_err(|e| format_err!("Error creating transaction request: {:?}", e))?; .map_err(|e| format_err!("Error creating transaction request: {:?}", e))?;
let txid = zip317_helper( let txid = spend(
(&mut db_data, prover, request), &mut db_data,
None, &network,
use_zip317_fees, &prover,
|(wallet_db, prover, request), input_selector| { &prover,
spend( &input_selector,
wallet_db, &usk,
&network, request,
&prover, OvkPolicy::Sender,
&prover, ANCHOR_OFFSET,
&input_selector, )
&usk, .map_err(|e| format_err!("Error while creating transaction: {}", e))?;
request,
OvkPolicy::Sender,
ANCHOR_OFFSET,
)
.map_err(|e| format_err!("Error while creating transaction: {}", e))
},
|(wallet_db, prover, request), input_selector| {
spend(
wallet_db,
&network,
&prover,
&prover,
&input_selector,
&usk,
request,
OvkPolicy::Sender,
ANCHOR_OFFSET,
)
.map_err(|e| format_err!("Error while creating transaction: {}", e))
},
)?;
utils::rust_bytes_to_java(&env, txid.as_ref()) utils::rust_bytes_to_java(&env, txid.as_ref())
}); });
@ -1497,43 +1458,24 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_internal_jni_RustBackend_sh
let memo = Memo::from_bytes(&memo_bytes).unwrap(); let memo = Memo::from_bytes(&memo_bytes).unwrap();
let input_selector = zip317_helper(Some(MemoBytes::from(&memo)), use_zip317_fees);
let prover = LocalTxProver::new(Path::new(&spend_params), Path::new(&output_params)); let prover = LocalTxProver::new(Path::new(&spend_params), Path::new(&output_params));
let shielding_threshold = NonNegativeAmount::from_u64(100000).unwrap(); let shielding_threshold = NonNegativeAmount::from_u64(100000).unwrap();
let txid = zip317_helper( let txid = shield_transparent_funds(
(&mut db_data, prover), &mut db_data,
Some(MemoBytes::from(&memo)), &network,
use_zip317_fees, &prover,
|(wallet_db, prover), input_selector| { &prover,
shield_transparent_funds( &input_selector,
wallet_db, shielding_threshold,
&network, &usk,
&prover, &from_addrs,
&prover, min_confirmations,
&input_selector, )
shielding_threshold, .map_err(|e| format_err!("Error while shielding transaction: {}", e))?;
&usk,
&from_addrs,
min_confirmations,
)
.map_err(|e| format_err!("Error while shielding transaction: {}", e))
},
|(wallet_db, prover), input_selector| {
shield_transparent_funds(
wallet_db,
&network,
&prover,
&prover,
&input_selector,
shielding_threshold,
&usk,
&from_addrs,
min_confirmations,
)
.map_err(|e| format_err!("Error while shielding transaction: {}", e))
},
)?;
utils::rust_bytes_to_java(&env, txid.as_ref()) utils::rust_bytes_to_java(&env, txid.as_ref())
}); });