darkfi_contract_test_harness/
contract_deploy.rs
1use darkfi::{
20 tx::{ContractCallLeaf, Transaction, TransactionBuilder},
21 Result,
22};
23use darkfi_deployooor_contract::{client::deploy_v1::DeployCallBuilder, DeployFunction};
24use darkfi_money_contract::{
25 client::{MoneyNote, OwnCoin},
26 model::MoneyFeeParamsV1,
27};
28use darkfi_sdk::{
29 crypto::{contract_id::DEPLOYOOOR_CONTRACT_ID, MerkleNode},
30 deploy::DeployParamsV1,
31 ContractCall,
32};
33use darkfi_serial::AsyncEncodable;
34use log::debug;
35
36use super::{Holder, TestHarness};
37
38impl TestHarness {
39 pub async fn deploy_contract(
43 &mut self,
44 holder: &Holder,
45 wasm_bincode: Vec<u8>,
46 block_height: u32,
47 ) -> Result<(Transaction, DeployParamsV1, Option<MoneyFeeParamsV1>)> {
48 let wallet = self.holders.get(holder).unwrap();
49 let deploy_keypair = wallet.contract_deploy_authority;
50
51 let builder = DeployCallBuilder { deploy_keypair, wasm_bincode, deploy_ix: vec![] };
53 let debris = builder.build()?;
54
55 let mut data = vec![DeployFunction::DeployV1 as u8];
57 debris.params.encode_async(&mut data).await?;
58 let call = ContractCall { contract_id: *DEPLOYOOOR_CONTRACT_ID, data };
59 let mut tx_builder =
60 TransactionBuilder::new(ContractCallLeaf { call, proofs: vec![] }, vec![])?;
61
62 let mut fee_params = None;
64 let mut fee_signature_secrets = None;
65 if self.verify_fees {
66 let mut tx = tx_builder.build()?;
67 let sigs = tx.create_sigs(&[deploy_keypair.secret])?;
68 tx.signatures = vec![sigs];
69
70 let (fee_call, fee_proofs, fee_secrets, _spent_fee_coins, fee_call_params) =
71 self.append_fee_call(holder, tx, block_height, &[]).await?;
72
73 tx_builder.append(ContractCallLeaf { call: fee_call, proofs: fee_proofs }, vec![])?;
75 fee_signature_secrets = Some(fee_secrets);
76 fee_params = Some(fee_call_params);
77 }
78
79 let mut tx = tx_builder.build()?;
81 let sigs = tx.create_sigs(&[deploy_keypair.secret])?;
82 tx.signatures = vec![sigs];
83 if let Some(fee_signature_secrets) = fee_signature_secrets {
84 let sigs = tx.create_sigs(&fee_signature_secrets)?;
85 tx.signatures.push(sigs);
86 }
87
88 Ok((tx, debris.params, fee_params))
89 }
90
91 pub async fn execute_deploy_tx(
95 &mut self,
96 holder: &Holder,
97 tx: Transaction,
98 _params: &DeployParamsV1,
99 fee_params: &Option<MoneyFeeParamsV1>,
100 block_height: u32,
101 append: bool,
102 ) -> Result<Vec<OwnCoin>> {
103 let wallet = self.holders.get_mut(holder).unwrap();
104
105 wallet.add_transaction("deploy::deploy", tx, block_height).await?;
107
108 if !append {
109 return Ok(vec![])
110 }
111
112 if let Some(ref fee_params) = fee_params {
113 let nullifier = fee_params.input.nullifier.inner();
114 wallet
115 .money_null_smt
116 .insert_batch(vec![(nullifier, nullifier)])
117 .expect("smt.insert_batch()");
118
119 if let Some(spent_coin) = wallet
120 .unspent_money_coins
121 .iter()
122 .find(|x| x.nullifier() == fee_params.input.nullifier)
123 .cloned()
124 {
125 debug!("Found spent OwnCoin({}) for {:?}", spent_coin.coin, holder);
126 wallet.unspent_money_coins.retain(|x| x.nullifier() != fee_params.input.nullifier);
127 wallet.spent_money_coins.push(spent_coin.clone());
128 }
129
130 wallet.money_merkle_tree.append(MerkleNode::from(fee_params.output.coin.inner()));
131
132 let Ok(note) = fee_params.output.note.decrypt::<MoneyNote>(&wallet.keypair.secret)
133 else {
134 return Ok(vec![])
135 };
136
137 let owncoin = OwnCoin {
138 coin: fee_params.output.coin,
139 note: note.clone(),
140 secret: wallet.keypair.secret,
141 leaf_position: wallet.money_merkle_tree.mark().unwrap(),
142 };
143
144 debug!("Found new OwnCoin({}) for {:?}", owncoin.coin, holder);
145 wallet.unspent_money_coins.push(owncoin.clone());
146 return Ok(vec![owncoin])
147 }
148
149 Ok(vec![])
150 }
151}