Ver Fonte

dao::propose()

x há 3 anos atrás
pai
commit
14c2a0246a

+ 2 - 2
src/contract/dao/proof/dao-propose-burn.zk

@@ -20,8 +20,8 @@ contract "DaoProposeInput" {
 }
 
 circuit "DaoProposeInput" {
-	nullifier = poseidon_hash(secret, serial);
-	constrain_instance(nullifier);
+	#nullifier = poseidon_hash(secret, serial);
+	#constrain_instance(nullifier);
 
 	# Pedersen commitment for coin's value
 	vcv = ec_mul_short(value, VALUE_COMMIT_VALUE);

+ 67 - 12
src/contract/dao/tests/dao_harness.rs

@@ -41,6 +41,8 @@ use darkfi_serial::serialize;
 use log::{info, warn};
 use rand::rngs::OsRng;
 
+use darkfi_money_contract::{MONEY_CONTRACT_ZKAS_BURN_NS_V1, MONEY_CONTRACT_ZKAS_MINT_NS_V1};
+
 use darkfi_dao_contract::{
     DAO_CONTRACT_ZKAS_DAO_EXEC_NS, DAO_CONTRACT_ZKAS_DAO_MINT_NS,
     DAO_CONTRACT_ZKAS_DAO_PROPOSE_BURN_NS, DAO_CONTRACT_ZKAS_DAO_PROPOSE_MAIN_NS,
@@ -48,26 +50,51 @@ use darkfi_dao_contract::{
 };
 
 pub struct DaoTestHarness {
+    /// Minting all new coins
+    pub faucet_kp: Keypair,
+    /// Governance token holder 1
     pub alice_kp: Keypair,
+    /// Governance token holder 2
+    pub bob_kp: Keypair,
+    /// Governance token holder 3
+    pub charlie_kp: Keypair,
+    /// Receiver for treasury tokens
+    pub rachel_kp: Keypair,
+    /// DAO keypair
     pub dao_kp: Keypair,
+
     pub alice_state: ValidatorStatePtr,
-    pub alice_dao_merkle_tree: MerkleTree,
     pub money_contract_id: ContractId,
     pub dao_contract_id: ContractId,
     pub proving_keys: HashMap<[u8; 32], Vec<(&'static str, ProvingKey)>>,
+
+    pub money_mint_zkbin: ZkBinary,
+    pub money_mint_pk: ProvingKey,
+
+    pub money_burn_zkbin: ZkBinary,
+    pub money_burn_pk: ProvingKey,
+
     pub dao_mint_zkbin: ZkBinary,
     pub dao_mint_pk: ProvingKey,
+
     pub dao_propose_burn_zkbin: ZkBinary,
     pub dao_propose_burn_pk: ProvingKey,
+
     pub dao_propose_main_zkbin: ZkBinary,
     pub dao_propose_main_pk: ProvingKey,
 }
 
 impl DaoTestHarness {
     pub async fn new() -> Result<Self> {
+        let faucet_kp = Keypair::random(&mut OsRng);
         let alice_kp = Keypair::random(&mut OsRng);
+        let bob_kp = Keypair::random(&mut OsRng);
+        let charlie_kp = Keypair::random(&mut OsRng);
+        let rachel_kp = Keypair::random(&mut OsRng);
         let dao_kp = Keypair::random(&mut OsRng);
 
+        let faucet_pubkeys = vec![faucet_kp.public];
+
         let alice_wallet = WalletDb::new("sqlite::memory:", "foo").await?;
 
         let alice_sled_db = sled::Config::new().temporary(true).open()?;
@@ -78,18 +105,21 @@ impl DaoTestHarness {
             *TESTNET_GENESIS_TIMESTAMP,
             *TESTNET_GENESIS_HASH_BYTES,
             alice_wallet,
-            vec![],
+            faucet_pubkeys,
             false,
         )
         .await?;
 
-        let alice_dao_merkle_tree = MerkleTree::new(100);
-
         let money_contract_id = *MONEY_CONTRACT_ID;
         let dao_contract_id = *DAO_CONTRACT_ID;
 
         let alice_sled = alice_state.read().await.blockchain.sled_db.clone();
-        let db_handle = alice_state.read().await.blockchain.contracts.lookup(
+        let money_db_handle = alice_state.read().await.blockchain.contracts.lookup(
+            &alice_sled,
+            &money_contract_id,
+            SMART_CONTRACT_ZKAS_DB_NAME,
+        )?;
+        let dao_db_handle = alice_state.read().await.blockchain.contracts.lookup(
             &alice_sled,
             &dao_contract_id,
             SMART_CONTRACT_ZKAS_DB_NAME,
@@ -97,40 +127,54 @@ impl DaoTestHarness {
 
         info!("Decoding bincode");
 
-        let dao_mint_zkbin = db_handle.get(&serialize(&DAO_CONTRACT_ZKAS_DAO_MINT_NS))?.unwrap();
+        let money_mint_zkbin =
+            money_db_handle.get(&serialize(&MONEY_CONTRACT_ZKAS_MINT_NS_V1))?.unwrap();
+        let money_mint_zkbin = ZkBinary::decode(&money_mint_zkbin)?;
+        let money_mint_witnesses = empty_witnesses(&money_mint_zkbin);
+        let money_mint_circuit = ZkCircuit::new(money_mint_witnesses, money_mint_zkbin.clone());
+
+        let money_burn_zkbin =
+            money_db_handle.get(&serialize(&MONEY_CONTRACT_ZKAS_BURN_NS_V1))?.unwrap();
+        let money_burn_zkbin = ZkBinary::decode(&money_burn_zkbin)?;
+        let money_burn_witnesses = empty_witnesses(&money_burn_zkbin);
+        let money_burn_circuit = ZkCircuit::new(money_burn_witnesses, money_burn_zkbin.clone());
+
+        let dao_mint_zkbin =
+            dao_db_handle.get(&serialize(&DAO_CONTRACT_ZKAS_DAO_MINT_NS))?.unwrap();
         let dao_mint_zkbin = ZkBinary::decode(&dao_mint_zkbin)?;
         let dao_mint_witnesses = empty_witnesses(&dao_mint_zkbin);
         let dao_mint_circuit = ZkCircuit::new(dao_mint_witnesses, dao_mint_zkbin.clone());
 
         let dao_propose_burn_zkbin =
-            db_handle.get(&serialize(&DAO_CONTRACT_ZKAS_DAO_PROPOSE_BURN_NS))?.unwrap();
+            dao_db_handle.get(&serialize(&DAO_CONTRACT_ZKAS_DAO_PROPOSE_BURN_NS))?.unwrap();
         let dao_propose_burn_zkbin = ZkBinary::decode(&dao_propose_burn_zkbin)?;
         let dao_propose_burn_witnesses = empty_witnesses(&dao_propose_burn_zkbin);
         let dao_propose_burn_circuit =
             ZkCircuit::new(dao_propose_burn_witnesses, dao_propose_burn_zkbin.clone());
 
         let dao_propose_main_zkbin =
-            db_handle.get(&serialize(&DAO_CONTRACT_ZKAS_DAO_PROPOSE_MAIN_NS))?.unwrap();
+            dao_db_handle.get(&serialize(&DAO_CONTRACT_ZKAS_DAO_PROPOSE_MAIN_NS))?.unwrap();
         let dao_propose_main_zkbin = ZkBinary::decode(&dao_propose_main_zkbin)?;
         let dao_propose_main_witnesses = empty_witnesses(&dao_propose_main_zkbin);
         let dao_propose_main_circuit =
             ZkCircuit::new(dao_propose_main_witnesses, dao_propose_main_zkbin.clone());
 
         let dao_vote_burn_zkbin =
-            db_handle.get(&serialize(&DAO_CONTRACT_ZKAS_DAO_VOTE_BURN_NS))?.unwrap();
+            dao_db_handle.get(&serialize(&DAO_CONTRACT_ZKAS_DAO_VOTE_BURN_NS))?.unwrap();
         let dao_vote_burn_zkbin = ZkBinary::decode(&dao_vote_burn_zkbin)?;
         let dao_vote_burn_witnesses = empty_witnesses(&dao_vote_burn_zkbin);
         let dao_vote_burn_circuit =
             ZkCircuit::new(dao_vote_burn_witnesses, dao_vote_burn_zkbin.clone());
 
         let dao_vote_main_zkbin =
-            db_handle.get(&serialize(&DAO_CONTRACT_ZKAS_DAO_VOTE_MAIN_NS))?.unwrap();
+            dao_db_handle.get(&serialize(&DAO_CONTRACT_ZKAS_DAO_VOTE_MAIN_NS))?.unwrap();
         let dao_vote_main_zkbin = ZkBinary::decode(&dao_vote_main_zkbin)?;
         let dao_vote_main_witnesses = empty_witnesses(&dao_vote_main_zkbin);
         let dao_vote_main_circuit =
             ZkCircuit::new(dao_vote_main_witnesses, dao_vote_main_zkbin.clone());
 
-        let dao_exec_zkbin = db_handle.get(&serialize(&DAO_CONTRACT_ZKAS_DAO_EXEC_NS))?.unwrap();
+        let dao_exec_zkbin =
+            dao_db_handle.get(&serialize(&DAO_CONTRACT_ZKAS_DAO_EXEC_NS))?.unwrap();
         let dao_exec_zkbin = ZkBinary::decode(&dao_exec_zkbin)?;
         let dao_exec_witnesses = empty_witnesses(&dao_exec_zkbin);
         let dao_exec_circuit = ZkCircuit::new(dao_exec_witnesses, dao_exec_zkbin.clone());
@@ -140,6 +184,8 @@ impl DaoTestHarness {
         let k = 13;
         let mut proving_keys = HashMap::<[u8; 32], Vec<(&str, ProvingKey)>>::new();
 
+        let money_mint_pk = ProvingKey::build(k, &money_mint_circuit);
+        let money_burn_pk = ProvingKey::build(k, &money_burn_circuit);
         let dao_mint_pk = ProvingKey::build(k, &dao_mint_circuit);
         let dao_propose_burn_pk = ProvingKey::build(k, &dao_propose_burn_circuit);
         let dao_propose_main_pk = ProvingKey::build(k, &dao_propose_main_circuit);
@@ -148,6 +194,8 @@ impl DaoTestHarness {
         let dao_exec_pk = ProvingKey::build(k, &dao_exec_circuit);
 
         let pks = vec![
+            (MONEY_CONTRACT_ZKAS_MINT_NS_V1, money_mint_pk.clone()),
+            (MONEY_CONTRACT_ZKAS_BURN_NS_V1, money_burn_pk.clone()),
             (DAO_CONTRACT_ZKAS_DAO_MINT_NS, dao_mint_pk.clone()),
             (DAO_CONTRACT_ZKAS_DAO_PROPOSE_BURN_NS, dao_propose_burn_pk.clone()),
             (DAO_CONTRACT_ZKAS_DAO_PROPOSE_MAIN_NS, dao_propose_burn_pk.clone()),
@@ -158,13 +206,20 @@ impl DaoTestHarness {
         proving_keys.insert(dao_contract_id.inner().to_repr(), pks);
 
         Ok(Self {
+            faucet_kp,
             alice_kp,
+            bob_kp,
+            charlie_kp,
+            rachel_kp,
             dao_kp,
             alice_state,
-            alice_dao_merkle_tree,
             money_contract_id,
             dao_contract_id,
             proving_keys,
+            money_mint_pk,
+            money_mint_zkbin,
+            money_burn_pk,
+            money_burn_zkbin,
             dao_mint_zkbin,
             dao_mint_pk,
             dao_propose_burn_zkbin,

+ 38 - 26
src/contract/dao/tests/integration.rs

@@ -19,7 +19,10 @@
 use darkfi::{tx::Transaction, Result};
 use darkfi_sdk::{
     crypto::{
-        coin::Coin, constants::MERKLE_DEPTH, contract_id::MONEY_CONTRACT_ID, keypair::Keypair,
+        coin::Coin,
+        constants::MERKLE_DEPTH,
+        contract_id::{DAO_CONTRACT_ID, MONEY_CONTRACT_ID},
+        keypair::Keypair,
         poseidon_hash, MerkleNode, SecretKey, TokenId,
     },
     incrementalmerkletree::{bridgetree::BridgeTree, Tree},
@@ -64,7 +67,6 @@ async fn integration_test() -> Result<()> {
     init_logger()?;
 
     let mut dao_th = DaoTestHarness::new().await?;
-    let mut money_th = MoneyTestHarness::new().await?;
 
     // Money parameters
     let xdrk_supply = 1_000_000;
@@ -163,7 +165,7 @@ async fn integration_test() -> Result<()> {
         clear_inputs: vec![money_client::BuilderClearInputInfo {
             value: xdrk_supply,
             token_id: xdrk_token_id,
-            signature_secret: money_th.faucet_kp.secret,
+            signature_secret: dao_th.faucet_kp.secret,
         }],
         inputs: vec![],
         outputs: vec![money_client::BuilderOutputInfo {
@@ -177,10 +179,10 @@ async fn integration_test() -> Result<()> {
         }],
     };
     let (params, proofs) = builder.build(
-        &money_th.mint_zkbin,
-        &money_th.mint_pk,
-        &money_th.burn_zkbin,
-        &money_th.burn_pk,
+        &dao_th.money_mint_zkbin,
+        &dao_th.money_mint_pk,
+        &dao_th.money_burn_zkbin,
+        &dao_th.money_burn_pk,
     )?;
 
     let contract_id = *MONEY_CONTRACT_ID;
@@ -190,11 +192,10 @@ async fn integration_test() -> Result<()> {
     let calls = vec![ContractCall { contract_id, data }];
     let proofs = vec![proofs];
     let mut tx = Transaction { calls, proofs, signatures: vec![] };
-    let sigs = tx.create_sigs(&mut OsRng, &vec![money_th.faucet_kp.secret])?;
+    let sigs = tx.create_sigs(&mut OsRng, &vec![dao_th.faucet_kp.secret])?;
     tx.signatures = vec![sigs];
 
-    money_th.faucet_state.read().await.verify_transactions(&[tx.clone()], true).await?;
-    money_th.faucet_merkle_tree.append(&MerkleNode::from(params.outputs[0].coin));
+    dao_th.alice_state.read().await.verify_transactions(&[tx.clone()], true).await?;
 
     // Wallet stuff
 
@@ -248,9 +249,9 @@ async fn integration_test() -> Result<()> {
     // =======================================================
     debug!(target: "demo", "Stage 3. Minting governance token");
 
-    cache.track(money_th.alice_kp.secret);
-    cache.track(money_th.bob_kp.secret);
-    cache.track(money_th.charlie_kp.secret);
+    cache.track(dao_th.alice_kp.secret);
+    cache.track(dao_th.bob_kp.secret);
+    cache.track(dao_th.charlie_kp.secret);
 
     // Spend hook and user data disabled
     let spend_hook = pallas::Base::from(0);
@@ -259,7 +260,7 @@ async fn integration_test() -> Result<()> {
     let output1 = money_client::BuilderOutputInfo {
         value: 400000,
         token_id: gdrk_token_id,
-        public: money_th.alice_kp.public,
+        public: dao_th.alice_kp.public,
         serial: pallas::Base::random(&mut OsRng),
         coin_blind: pallas::Base::random(&mut OsRng),
         spend_hook,
@@ -269,7 +270,7 @@ async fn integration_test() -> Result<()> {
     let output2 = money_client::BuilderOutputInfo {
         value: 400000,
         token_id: gdrk_token_id,
-        public: money_th.bob_kp.public,
+        public: dao_th.bob_kp.public,
         serial: pallas::Base::random(&mut OsRng),
         coin_blind: pallas::Base::random(&mut OsRng),
         spend_hook,
@@ -279,7 +280,7 @@ async fn integration_test() -> Result<()> {
     let output3 = money_client::BuilderOutputInfo {
         value: 200000,
         token_id: gdrk_token_id,
-        public: money_th.charlie_kp.public,
+        public: dao_th.charlie_kp.public,
         serial: pallas::Base::random(&mut OsRng),
         coin_blind: pallas::Base::random(&mut OsRng),
         spend_hook,
@@ -293,16 +294,16 @@ async fn integration_test() -> Result<()> {
             value: gdrk_supply,
             token_id: gdrk_token_id,
             // This might be different for various tokens but lets reuse it here
-            signature_secret: money_th.faucet_kp.secret,
+            signature_secret: dao_th.faucet_kp.secret,
         }],
         inputs: vec![],
         outputs: vec![output1, output2, output3],
     };
     let (params, proofs) = builder.build(
-        &money_th.mint_zkbin,
-        &money_th.mint_pk,
-        &money_th.burn_zkbin,
-        &money_th.burn_pk,
+        &dao_th.money_mint_zkbin,
+        &dao_th.money_mint_pk,
+        &dao_th.money_burn_zkbin,
+        &dao_th.money_burn_pk,
     )?;
 
     let contract_id = *MONEY_CONTRACT_ID;
@@ -312,11 +313,10 @@ async fn integration_test() -> Result<()> {
     let calls = vec![ContractCall { contract_id, data }];
     let proofs = vec![proofs];
     let mut tx = Transaction { calls, proofs, signatures: vec![] };
-    let sigs = tx.create_sigs(&mut OsRng, &vec![money_th.faucet_kp.secret])?;
+    let sigs = tx.create_sigs(&mut OsRng, &vec![dao_th.faucet_kp.secret])?;
     tx.signatures = vec![sigs];
 
-    money_th.faucet_state.read().await.verify_transactions(&[tx.clone()], true).await?;
-    money_th.faucet_merkle_tree.append(&MerkleNode::from(params.outputs[0].coin));
+    dao_th.alice_state.read().await.verify_transactions(&[tx.clone()], true).await?;
 
     // Wallet
     {
@@ -334,7 +334,7 @@ async fn integration_test() -> Result<()> {
         }
     }
 
-    let gov_keypairs = vec![money_th.alice_kp, money_th.bob_kp, money_th.charlie_kp];
+    let gov_keypairs = vec![dao_th.alice_kp, dao_th.bob_kp, dao_th.charlie_kp];
     let mut gov_recv = vec![None, None, None];
     // Check that each person received one coin
     for (i, key) in gov_keypairs.iter().enumerate() {
@@ -405,7 +405,7 @@ async fn integration_test() -> Result<()> {
     //       need to look into this
     let signature_secret = SecretKey::random(&mut OsRng);
     let input = dao_propose_client::BuilderInput {
-        secret: money_th.alice_kp.secret,
+        secret: dao_th.alice_kp.secret,
         note: gov_recv[0].note.clone(),
         leaf_position: money_leaf_position,
         merkle_path: money_merkle_path,
@@ -452,5 +452,17 @@ async fn integration_test() -> Result<()> {
         &dao_th.dao_propose_main_pk,
     )?;
 
+    let contract_id = *DAO_CONTRACT_ID;
+
+    let mut data = vec![DaoFunction::Propose as u8];
+    params.encode(&mut data)?;
+    let calls = vec![ContractCall { contract_id, data }];
+    let proofs = vec![proofs];
+    let mut tx = Transaction { calls, proofs, signatures: vec![] };
+    let sigs = tx.create_sigs(&mut OsRng, &vec![signature_secret])?;
+    tx.signatures = vec![sigs];
+
+    dao_th.alice_state.read().await.verify_transactions(&[tx.clone()], true).await?;
+
     Ok(())
 }

+ 2 - 2
src/contract/money/tests/harness.rs

@@ -53,8 +53,8 @@ pub fn init_logger() -> Result<()> {
     let mut cfg = simplelog::ConfigBuilder::new();
     cfg.add_filter_ignore("sled".to_string());
     if let Err(_) = simplelog::TermLogger::init(
-        simplelog::LevelFilter::Info,
-        //simplelog::LevelFilter::Debug,
+        //simplelog::LevelFilter::Info,
+        simplelog::LevelFilter::Debug,
         //simplelog::LevelFilter::Trace,
         cfg.build(),
         simplelog::TerminalMode::Mixed,