darkfi_contract_test_harness/
dao_mint.rs
1use darkfi::{
20 tx::{ContractCallLeaf, Transaction, TransactionBuilder},
21 Result,
22};
23use darkfi_dao_contract::{
24 client::make_mint_call,
25 model::{Dao, DaoMintParams},
26 DaoFunction, DAO_CONTRACT_ZKAS_DAO_MINT_NS,
27};
28use darkfi_money_contract::{
29 client::{MoneyNote, OwnCoin},
30 model::MoneyFeeParamsV1,
31};
32use darkfi_sdk::{
33 crypto::{contract_id::DAO_CONTRACT_ID, MerkleNode, SecretKey},
34 ContractCall,
35};
36use darkfi_serial::AsyncEncodable;
37use log::debug;
38
39use super::{Holder, TestHarness};
40
41impl TestHarness {
42 #[allow(clippy::too_many_arguments)]
47 pub async fn dao_mint(
48 &mut self,
49 holder: &Holder,
50 dao: &Dao,
51 dao_notes_secret_key: &SecretKey,
52 dao_proposer_secret_key: &SecretKey,
53 dao_proposals_secret_key: &SecretKey,
54 dao_votes_secret_key: &SecretKey,
55 dao_exec_secret_key: &SecretKey,
56 dao_early_exec_secret_key: &SecretKey,
57 block_height: u32,
58 ) -> Result<(Transaction, DaoMintParams, Option<MoneyFeeParamsV1>)> {
59 let (dao_mint_pk, dao_mint_zkbin) =
60 self.proving_keys.get(DAO_CONTRACT_ZKAS_DAO_MINT_NS).unwrap();
61
62 let (params, proofs) = make_mint_call(
64 dao,
65 dao_notes_secret_key,
66 dao_proposer_secret_key,
67 dao_proposals_secret_key,
68 dao_votes_secret_key,
69 dao_exec_secret_key,
70 dao_early_exec_secret_key,
71 dao_mint_zkbin,
72 dao_mint_pk,
73 )?;
74
75 let mut data = vec![DaoFunction::Mint as u8];
77 params.encode_async(&mut data).await?;
78 let call = ContractCall { contract_id: *DAO_CONTRACT_ID, data };
79 let mut tx_builder = TransactionBuilder::new(ContractCallLeaf { call, proofs }, vec![])?;
80
81 let mut fee_params = None;
83 let mut fee_signature_secrets = None;
84 if self.verify_fees {
85 let mut tx = tx_builder.build()?;
86 let sigs = tx.create_sigs(&[*dao_notes_secret_key])?;
87 tx.signatures = vec![sigs];
88
89 let (fee_call, fee_proofs, fee_secrets, _spent_fee_coins, fee_call_params) =
90 self.append_fee_call(holder, tx, block_height, &[]).await?;
91
92 tx_builder.append(ContractCallLeaf { call: fee_call, proofs: fee_proofs }, vec![])?;
94 fee_signature_secrets = Some(fee_secrets);
95 fee_params = Some(fee_call_params);
96 }
97
98 let mut tx = tx_builder.build()?;
100 let sigs = tx.create_sigs(&[*dao_notes_secret_key])?;
101 tx.signatures = vec![sigs];
102 if let Some(fee_signature_secrets) = fee_signature_secrets {
103 let sigs = tx.create_sigs(&fee_signature_secrets)?;
104 tx.signatures.push(sigs);
105 }
106
107 Ok((tx, params, fee_params))
108 }
109
110 pub async fn execute_dao_mint_tx(
114 &mut self,
115 holder: &Holder,
116 tx: Transaction,
117 params: &DaoMintParams,
118 fee_params: &Option<MoneyFeeParamsV1>,
119 block_height: u32,
120 append: bool,
121 ) -> Result<Vec<OwnCoin>> {
122 let wallet = self.holders.get_mut(holder).unwrap();
123
124 wallet.add_transaction("dao::mint", tx, block_height).await?;
126
127 if !append {
128 return Ok(vec![])
129 }
130
131 wallet.dao_merkle_tree.append(MerkleNode::from(params.dao_bulla.inner()));
132 let leaf_pos = wallet.dao_merkle_tree.mark().unwrap();
133 wallet.dao_leafs.insert(params.dao_bulla, leaf_pos);
134
135 if let Some(ref fee_params) = fee_params {
136 let nullifier = fee_params.input.nullifier.inner();
137 wallet
138 .money_null_smt
139 .insert_batch(vec![(nullifier, nullifier)])
140 .expect("smt.insert_batch()");
141
142 if let Some(spent_coin) = wallet
143 .unspent_money_coins
144 .iter()
145 .find(|x| x.nullifier() == fee_params.input.nullifier)
146 .cloned()
147 {
148 debug!("Found spent OwnCoin({}) for {:?}", spent_coin.coin, holder);
149 wallet.unspent_money_coins.retain(|x| x.nullifier() != fee_params.input.nullifier);
150 wallet.spent_money_coins.push(spent_coin.clone());
151 }
152
153 wallet.money_merkle_tree.append(MerkleNode::from(fee_params.output.coin.inner()));
154
155 let Ok(note) = fee_params.output.note.decrypt::<MoneyNote>(&wallet.keypair.secret)
156 else {
157 return Ok(vec![])
158 };
159
160 let owncoin = OwnCoin {
161 coin: fee_params.output.coin,
162 note: note.clone(),
163 secret: wallet.keypair.secret,
164 leaf_position: wallet.money_merkle_tree.mark().unwrap(),
165 };
166
167 debug!("Found new OwnCoin({}) for {:?}", owncoin.coin, holder);
168 wallet.unspent_money_coins.push(owncoin.clone());
169 return Ok(vec![owncoin])
170 }
171
172 Ok(vec![])
173 }
174}