-
Notifications
You must be signed in to change notification settings - Fork 117
feat(tests): zcoin unit test to validate dex fee #2460
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
5a841c6
518b7ae
820532e
fa7bf0d
d74cefe
52a1b47
bd45704
d9a58e9
d8d59fc
10caa50
196a597
e0492b7
62bcffe
ae28620
fd4f2e2
be3818d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -678,7 +678,7 @@ impl ZCoin { | |||||||||||||||||||||||||||
| else { | ||||||||||||||||||||||||||||
| return Ok(false); | ||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||
| if &address == expected_address { | ||||||||||||||||||||||||||||
| if &address != expected_address { | ||||||||||||||||||||||||||||
|
shamardy marked this conversation as resolved.
|
||||||||||||||||||||||||||||
| return Ok(false); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| if note.value != amount_sat { | ||||||||||||||||||||||||||||
|
|
@@ -783,6 +783,8 @@ pub enum ZcoinRpcMode { | |||||||||||||||||||||||||||
| /// Will use `sync_params` if no last synced block found. | ||||||||||||||||||||||||||||
| skip_sync_params: Option<bool>, | ||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||
| #[cfg(all(test, not(target_arch = "wasm32")))] | ||||||||||||||||||||||||||||
| UnitTests, | ||||||||||||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can't we do the tests for wasm as well using
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried to make it a cross_test and was getting a failure on wasm with an error in zcash_proofs/bellman::multicore mod: I managed to fix this error to by disabling the multicore feature in zcash_proofs for wasm dependencies (like it had been before the workspace dependencies PR #2449. See zcash_proofs in the main branch Cargo.toml ). PS However the wasm test still would not work as looks like mocktopus is not working there There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. weird, even tho There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dimxy please could you be more specific on the issue you had using mocktopus in wasm? |
||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| #[derive(Clone, Deserialize)] | ||||||||||||||||||||||||||||
|
|
@@ -964,6 +966,8 @@ impl<'a> UtxoCoinBuilder for ZCoinBuilder<'a> { | |||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||
| .await? | ||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||
| #[cfg(all(test, not(target_arch = "wasm32")))] | ||||||||||||||||||||||||||||
| ZcoinRpcMode::UnitTests => tests::create_test_sync_connector(&self).await, | ||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| let z_fields = Arc::new(ZCoinFields { | ||||||||||||||||||||||||||||
|
|
@@ -1008,6 +1012,12 @@ impl<'a> ZCoinBuilder<'a> { | |||||||||||||||||||||||||||
| min_connected: *min_connected, | ||||||||||||||||||||||||||||
| max_connected: *max_connected, | ||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||
| #[cfg(test)] | ||||||||||||||||||||||||||||
| ZcoinRpcMode::UnitTests => UtxoRpcMode::Electrum { | ||||||||||||||||||||||||||||
| servers: vec![], | ||||||||||||||||||||||||||||
| min_connected: None, | ||||||||||||||||||||||||||||
| max_connected: Some(1), | ||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||
| let utxo_params = UtxoActivationParams { | ||||||||||||||||||||||||||||
| mode: utxo_mode, | ||||||||||||||||||||||||||||
|
|
@@ -2064,3 +2074,275 @@ fn test_interpret_memo_string() { | |||||||||||||||||||||||||||
| let expected = MemoBytes::from_bytes(&hex::decode("68656c6c6f207a63617368").unwrap()).unwrap(); | ||||||||||||||||||||||||||||
| assert_eq!(actual, expected); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| #[cfg(all(test, not(target_arch = "wasm32")))] | ||||||||||||||||||||||||||||
| mod tests { | ||||||||||||||||||||||||||||
| use super::*; | ||||||||||||||||||||||||||||
| use crate::utxo::rpc_clients::ElectrumClient; | ||||||||||||||||||||||||||||
| use crate::utxo::rpc_clients::UtxoRpcClientOps; | ||||||||||||||||||||||||||||
| use crate::z_coin::storage::WalletDbShared; | ||||||||||||||||||||||||||||
| use crate::CoinProtocol; | ||||||||||||||||||||||||||||
| use crate::DexFeeBurnDestination; | ||||||||||||||||||||||||||||
| use common::executor::spawn_abortable; | ||||||||||||||||||||||||||||
| use ff::{Field, PrimeField}; | ||||||||||||||||||||||||||||
|
shamardy marked this conversation as resolved.
Outdated
|
||||||||||||||||||||||||||||
| use futures::channel::mpsc::channel; | ||||||||||||||||||||||||||||
| use futures::lock::Mutex as AsyncMutex; | ||||||||||||||||||||||||||||
| use lazy_static::lazy_static; | ||||||||||||||||||||||||||||
| use mm2_core::mm_ctx::{MmArc, MmCtxBuilder}; | ||||||||||||||||||||||||||||
| use mm2_test_helpers::for_tests::zombie_conf; | ||||||||||||||||||||||||||||
| use mocktopus::mocking::*; | ||||||||||||||||||||||||||||
| use rand::rngs::OsRng; | ||||||||||||||||||||||||||||
| use rand::RngCore; | ||||||||||||||||||||||||||||
| use tempfile::TempDir; | ||||||||||||||||||||||||||||
| use tokio::sync::Mutex as TokioMutex; | ||||||||||||||||||||||||||||
| use zcash_primitives::merkle_tree::CommitmentTree; | ||||||||||||||||||||||||||||
| use zcash_primitives::merkle_tree::IncrementalWitness; | ||||||||||||||||||||||||||||
| use zcash_primitives::sapling::Node; | ||||||||||||||||||||||||||||
| use zcash_primitives::sapling::Rseed; | ||||||||||||||||||||||||||||
| use zcash_primitives::transaction::components::amount::DEFAULT_FEE; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| lazy_static! { | ||||||||||||||||||||||||||||
| static ref TEMP_DIR: TokioMutex<TempDir> = TokioMutex::new(TempDir::new().unwrap()); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
shamardy marked this conversation as resolved.
Outdated
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| pub(crate) async fn create_test_sync_connector<'a>( | ||||||||||||||||||||||||||||
| builder: &ZCoinBuilder<'a>, | ||||||||||||||||||||||||||||
| ) -> (AsyncMutex<SaplingSyncConnector>, WalletDbShared) { | ||||||||||||||||||||||||||||
| let wallet_db = WalletDbShared::new(builder, None, builder.z_spending_key.as_ref().unwrap(), true) | ||||||||||||||||||||||||||||
| .await | ||||||||||||||||||||||||||||
| .unwrap(); // Note: assuming we have a spending key in the builder | ||||||||||||||||||||||||||||
| let (_, sync_watcher) = channel(1); | ||||||||||||||||||||||||||||
| let (on_tx_gen_notifier, _) = channel(1); | ||||||||||||||||||||||||||||
| let abort_handle = spawn_abortable(futures::future::ready(())); | ||||||||||||||||||||||||||||
| let first_sync_block = FirstSyncBlock { | ||||||||||||||||||||||||||||
| requested: 0, | ||||||||||||||||||||||||||||
| is_pre_sapling: false, | ||||||||||||||||||||||||||||
| actual: 0, | ||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||
| let sync_state_connector = | ||||||||||||||||||||||||||||
| SaplingSyncConnector::new_mutex_wrapped(sync_watcher, on_tx_gen_notifier, abort_handle, first_sync_block); | ||||||||||||||||||||||||||||
| (sync_state_connector, wallet_db) | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| #[allow(clippy::too_many_arguments)] | ||||||||||||||||||||||||||||
| async fn z_coin_from_conf_and_params_for_tests( | ||||||||||||||||||||||||||||
| ctx: &MmArc, | ||||||||||||||||||||||||||||
| ticker: &str, | ||||||||||||||||||||||||||||
| conf: &Json, | ||||||||||||||||||||||||||||
| params: &ZcoinActivationParams, | ||||||||||||||||||||||||||||
| priv_key_policy: PrivKeyBuildPolicy, | ||||||||||||||||||||||||||||
| db_dir_path: PathBuf, | ||||||||||||||||||||||||||||
| protocol_info: ZcoinProtocolInfo, | ||||||||||||||||||||||||||||
| spending_key: &str, | ||||||||||||||||||||||||||||
| ) -> Result<ZCoin, MmError<ZCoinBuildError>> { | ||||||||||||||||||||||||||||
| use zcash_client_backend::encoding::decode_extended_spending_key; | ||||||||||||||||||||||||||||
| let z_spending_key = | ||||||||||||||||||||||||||||
| decode_extended_spending_key(z_mainnet_constants::HRP_SAPLING_EXTENDED_SPENDING_KEY, spending_key) | ||||||||||||||||||||||||||||
| .unwrap() | ||||||||||||||||||||||||||||
| .unwrap(); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| let builder = ZCoinBuilder::new( | ||||||||||||||||||||||||||||
| ctx, | ||||||||||||||||||||||||||||
| ticker, | ||||||||||||||||||||||||||||
| conf, | ||||||||||||||||||||||||||||
| params, | ||||||||||||||||||||||||||||
| priv_key_policy, | ||||||||||||||||||||||||||||
| db_dir_path, | ||||||||||||||||||||||||||||
| Some(z_spending_key), | ||||||||||||||||||||||||||||
| protocol_info, | ||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| builder.build().await | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| /// Build asset `ZCoin` for unit tests. | ||||||||||||||||||||||||||||
| async fn z_coin_from_spending_key_for_unit_test(spending_key: &str, path: &str) -> (MmArc, ZCoin) { | ||||||||||||||||||||||||||||
| let ctx = MmCtxBuilder::new().into_mm_arc(); | ||||||||||||||||||||||||||||
| let mut conf = zombie_conf(); | ||||||||||||||||||||||||||||
| let params = ZcoinActivationParams { | ||||||||||||||||||||||||||||
| mode: ZcoinRpcMode::UnitTests, | ||||||||||||||||||||||||||||
| ..Default::default() | ||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||
| let pk_data = [1; 32]; | ||||||||||||||||||||||||||||
| let tmp = TEMP_DIR.lock().await; | ||||||||||||||||||||||||||||
| let db_folder = tmp.path().join(format!("ZOMBIE_DB_{path}")); | ||||||||||||||||||||||||||||
| std::fs::create_dir_all(&db_folder).unwrap(); | ||||||||||||||||||||||||||||
| let protocol_info = match serde_json::from_value::<CoinProtocol>(conf["protocol"].take()).unwrap() { | ||||||||||||||||||||||||||||
| CoinProtocol::ZHTLC(protocol_info) => protocol_info, | ||||||||||||||||||||||||||||
| other_protocol => panic!("Failed to get protocol from config: {:?}", other_protocol), | ||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| let coin = z_coin_from_conf_and_params_for_tests( | ||||||||||||||||||||||||||||
| &ctx, | ||||||||||||||||||||||||||||
| "ZOMBIE", | ||||||||||||||||||||||||||||
| &conf, | ||||||||||||||||||||||||||||
| ¶ms, | ||||||||||||||||||||||||||||
| PrivKeyBuildPolicy::IguanaPrivKey(pk_data.into()), | ||||||||||||||||||||||||||||
| db_folder, | ||||||||||||||||||||||||||||
| protocol_info, | ||||||||||||||||||||||||||||
| spending_key, | ||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||
| .await | ||||||||||||||||||||||||||||
| .unwrap(); | ||||||||||||||||||||||||||||
| (ctx, coin) | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| fn add_test_spend<P: Parameters, R: RngCore>(coin: &ZCoin, tx_builder: &mut ZTxBuilder<P, R>, amount: u64) { | ||||||||||||||||||||||||||||
| let extsk = coin.z_fields.z_spending_key.clone(); | ||||||||||||||||||||||||||||
| let extfvk = coin.z_fields.evk.clone(); | ||||||||||||||||||||||||||||
| let to = extfvk.default_address().unwrap().1; | ||||||||||||||||||||||||||||
| let mut rng = OsRng; | ||||||||||||||||||||||||||||
| let note1 = to | ||||||||||||||||||||||||||||
| .create_note(amount, Rseed::BeforeZip212(jubjub::Fr::random(&mut rng))) | ||||||||||||||||||||||||||||
| .unwrap(); | ||||||||||||||||||||||||||||
| let cmu1 = Node::new(note1.cmu().to_repr()); | ||||||||||||||||||||||||||||
| let mut tree = CommitmentTree::empty(); | ||||||||||||||||||||||||||||
| tree.append(cmu1).unwrap(); | ||||||||||||||||||||||||||||
| let witness1 = IncrementalWitness::from_tree(&tree); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| tx_builder | ||||||||||||||||||||||||||||
| .add_sapling_spend(extsk, *to.diversifier(), note1, witness1.path().unwrap()) | ||||||||||||||||||||||||||||
| .unwrap(); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| async fn validate_fee_caller( | ||||||||||||||||||||||||||||
| coin: &ZCoin, | ||||||||||||||||||||||||||||
| dex_params: (PaymentAddress, u64), | ||||||||||||||||||||||||||||
| burn_params: Option<(PaymentAddress, u64)>, | ||||||||||||||||||||||||||||
| dex_fee: &DexFee, | ||||||||||||||||||||||||||||
| ) -> ValidatePaymentResult<()> { | ||||||||||||||||||||||||||||
| let uuid = &[1; 16]; | ||||||||||||||||||||||||||||
| let mut z_outputs = vec![]; | ||||||||||||||||||||||||||||
| let mut tx_builder = ZTxBuilder::new(coin.consensus_params(), BlockHeight::from_u32(1)); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| add_test_spend( | ||||||||||||||||||||||||||||
| coin, | ||||||||||||||||||||||||||||
| &mut tx_builder, | ||||||||||||||||||||||||||||
| dex_params.1 | ||||||||||||||||||||||||||||
| + if let Some(ref burn_params) = burn_params { | ||||||||||||||||||||||||||||
| burn_params.1 | ||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||
| 0 | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| + u64::from(DEFAULT_FEE), | ||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| let dex_fee_out = ZOutput { | ||||||||||||||||||||||||||||
| to_addr: dex_params.0, | ||||||||||||||||||||||||||||
| amount: Amount::from_u64(dex_params.1).unwrap(), | ||||||||||||||||||||||||||||
| viewing_key: Some(DEX_FEE_OVK), | ||||||||||||||||||||||||||||
| memo: Some(MemoBytes::from_bytes(uuid).expect("uuid length < 512")), | ||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||
| z_outputs.push(dex_fee_out); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // add output to the dex burn address: | ||||||||||||||||||||||||||||
| if let Some(burn_params) = burn_params { | ||||||||||||||||||||||||||||
| let dex_burn_out = ZOutput { | ||||||||||||||||||||||||||||
| to_addr: burn_params.0, | ||||||||||||||||||||||||||||
| amount: Amount::from_u64(burn_params.1).unwrap(), | ||||||||||||||||||||||||||||
| viewing_key: Some(DEX_FEE_OVK), | ||||||||||||||||||||||||||||
| memo: Some(MemoBytes::from_bytes(uuid).expect("uuid length < 512")), | ||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||
| z_outputs.push(dex_burn_out); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| for z_out in z_outputs { | ||||||||||||||||||||||||||||
| tx_builder | ||||||||||||||||||||||||||||
| .add_sapling_output(z_out.viewing_key, z_out.to_addr, z_out.amount, z_out.memo) | ||||||||||||||||||||||||||||
| .unwrap(); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| let (tx, _) = async_blocking({ | ||||||||||||||||||||||||||||
| let prover = coin.z_fields.z_tx_prover.clone(); | ||||||||||||||||||||||||||||
| move || tx_builder.build(BranchId::Sapling, prover.as_ref()) | ||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||
| .await | ||||||||||||||||||||||||||||
| .unwrap(); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| let tx: TransactionEnum = tx.into(); | ||||||||||||||||||||||||||||
| let tx_ret = tx.clone(); | ||||||||||||||||||||||||||||
| ElectrumClient::get_verbose_transaction.mock_safe(move |_, txid| { | ||||||||||||||||||||||||||||
| let bytes: BytesJson = tx_ret.tx_hex().into(); | ||||||||||||||||||||||||||||
| MockResult::Return(Box::new(futures01::future::ok(RpcTransaction { | ||||||||||||||||||||||||||||
| txid: *txid, | ||||||||||||||||||||||||||||
| hash: None, | ||||||||||||||||||||||||||||
| blockhash: H256Json::default(), | ||||||||||||||||||||||||||||
| confirmations: 0, | ||||||||||||||||||||||||||||
| time: 0, | ||||||||||||||||||||||||||||
| blocktime: 0, | ||||||||||||||||||||||||||||
| hex: bytes, | ||||||||||||||||||||||||||||
| vout: vec![], | ||||||||||||||||||||||||||||
| vin: vec![], | ||||||||||||||||||||||||||||
| size: None, | ||||||||||||||||||||||||||||
| version: 4, | ||||||||||||||||||||||||||||
| locktime: 0, | ||||||||||||||||||||||||||||
| vsize: None, | ||||||||||||||||||||||||||||
| rawconfirmations: None, | ||||||||||||||||||||||||||||
| height: None, | ||||||||||||||||||||||||||||
| }))) | ||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||
| let validate_fee_args = ValidateFeeArgs { | ||||||||||||||||||||||||||||
| fee_tx: &tx, | ||||||||||||||||||||||||||||
| expected_sender: &[], | ||||||||||||||||||||||||||||
| dex_fee, | ||||||||||||||||||||||||||||
| min_block_number: 1, | ||||||||||||||||||||||||||||
| uuid: &[1; 16], | ||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||
| coin.validate_fee(validate_fee_args).await | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| #[tokio::test] | ||||||||||||||||||||||||||||
| async fn test_validate_zcoin_dex_fee() { | ||||||||||||||||||||||||||||
|
shamardy marked this conversation as resolved.
Outdated
|
||||||||||||||||||||||||||||
| let (_ctx, coin) = z_coin_from_spending_key_for_unit_test("secret-extended-key-main1qvqstxphqyqqpqqnh3hstqpdjzkpadeed6u7fz230jmm2mxl0aacrtu9vt7a7rmr2w5az5u79d24t0rudak3newknrz5l0m3dsd8m4dffqh5xwyldc5qwz8pnalrnhlxdzf900x83jazc52y25e9hvyd4kepaze6nlcvk8sd8a4qjh3e9j5d6730t7ctzhhrhp0zljjtwuptadnksxf8a8y5axwdhass5pjaxg0hzhg7z25rx0rll7a6txywl32s6cda0s5kexr03uqdtelwe", "we").await; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| let std_fee = DexFee::Standard("0.001".into()); | ||||||||||||||||||||||||||||
| let with_burn = DexFee::WithBurn { | ||||||||||||||||||||||||||||
| fee_amount: "0.0075".into(), | ||||||||||||||||||||||||||||
| burn_amount: "0.0025".into(), | ||||||||||||||||||||||||||||
| burn_destination: DexFeeBurnDestination::PreBurnAccount, | ||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||
| assert!( | ||||||||||||||||||||||||||||
| validate_fee_caller(&coin, (coin.z_fields.dex_fee_addr.clone(), 100000), None, &std_fee) | ||||||||||||||||||||||||||||
| .await | ||||||||||||||||||||||||||||
| .is_ok() | ||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||
| assert!(validate_fee_caller( | ||||||||||||||||||||||||||||
| &coin, | ||||||||||||||||||||||||||||
| (coin.z_fields.dex_fee_addr.clone(), 750000), | ||||||||||||||||||||||||||||
| Some((coin.z_fields.dex_burn_addr.clone(), 250000)), | ||||||||||||||||||||||||||||
| &with_burn | ||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||
| .await | ||||||||||||||||||||||||||||
| .is_ok()); | ||||||||||||||||||||||||||||
| // try reverted addresses | ||||||||||||||||||||||||||||
| assert!(validate_fee_caller( | ||||||||||||||||||||||||||||
| &coin, | ||||||||||||||||||||||||||||
| (coin.z_fields.dex_burn_addr.clone(), 750000), | ||||||||||||||||||||||||||||
| Some((coin.z_fields.dex_fee_addr.clone(), 250000)), | ||||||||||||||||||||||||||||
| &with_burn | ||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||
| .await | ||||||||||||||||||||||||||||
| .is_err()); | ||||||||||||||||||||||||||||
| let other_addr = decode_payment_address( | ||||||||||||||||||||||||||||
| coin.z_fields.consensus_params.hrp_sapling_payment_address(), | ||||||||||||||||||||||||||||
| "zs182ht30wnnnr8jjhj2j9v5dkx3qsknnr5r00jfwk2nczdtqy7w0v836kyy840kv2r8xle5gcl549", | ||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||
| .expect("valid z address format") | ||||||||||||||||||||||||||||
| .expect("valid z address"); | ||||||||||||||||||||||||||||
| // try invalid dex address | ||||||||||||||||||||||||||||
| assert!(validate_fee_caller( | ||||||||||||||||||||||||||||
| &coin, | ||||||||||||||||||||||||||||
| (other_addr.clone(), 750000), | ||||||||||||||||||||||||||||
| Some((coin.z_fields.dex_burn_addr.clone(), 250000)), | ||||||||||||||||||||||||||||
| &with_burn | ||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||
| .await | ||||||||||||||||||||||||||||
| .is_err()); | ||||||||||||||||||||||||||||
| // try invalid burn address | ||||||||||||||||||||||||||||
| assert!(validate_fee_caller( | ||||||||||||||||||||||||||||
| &coin, | ||||||||||||||||||||||||||||
| (coin.z_fields.dex_fee_addr.clone(), 750000), | ||||||||||||||||||||||||||||
| Some((other_addr.clone(), 250000)), | ||||||||||||||||||||||||||||
| &with_burn | ||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||
| .await | ||||||||||||||||||||||||||||
| .is_err()); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
shamardy marked this conversation as resolved.
Outdated
|
||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.