Bladeren bron

add dao::exec() skeleton

x 3 jaren geleden
bovenliggende
commit
15ba8b1a9c
3 gewijzigde bestanden met toevoegingen van 264 en 24 verwijderingen
  1. 236 0
      src/contract/dao/src/dao_exec_client.rs
  2. 4 0
      src/contract/dao/src/lib.rs
  3. 24 24
      src/contract/dao/tests/integration.rs

+ 236 - 0
src/contract/dao/src/dao_exec_client.rs

@@ -0,0 +1,236 @@
+/* This file is part of DarkFi (https://dark.fi)
+ *
+ * Copyright (C) 2020-2022 Dyne.org foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+use darkfi_sdk::{
+    crypto::{
+        pedersen::pedersen_commitment_u64, poseidon_hash, MerkleNode, PublicKey, SecretKey, TokenId,
+    },
+    incrementalmerkletree,
+    incrementalmerkletree::{bridgetree::BridgeTree, Hashable, Tree},
+    pasta::{
+        arithmetic::CurveAffine,
+        group::{
+            ff::{Field, PrimeField},
+            Curve,
+        },
+        pallas,
+    },
+};
+use darkfi_serial::{SerialDecodable, SerialEncodable};
+use halo2_proofs::circuit::Value;
+use log::{debug, info};
+use rand::rngs::OsRng;
+
+use darkfi::{
+    zk::{
+        proof::{Proof, ProvingKey},
+        vm::ZkCircuit,
+        vm_stack::Witness,
+    },
+    zkas::ZkBinary,
+    Error, Result,
+};
+
+use crate::dao_propose_client::{DaoParams, Proposal};
+
+pub struct Builder {
+    pub proposal: Proposal,
+    pub dao: DaoParams,
+    pub yes_votes_value: u64,
+    pub all_votes_value: u64,
+    pub yes_votes_blind: pallas::Scalar,
+    pub all_votes_blind: pallas::Scalar,
+    pub user_serial: pallas::Base,
+    pub user_coin_blind: pallas::Base,
+    pub dao_serial: pallas::Base,
+    pub dao_coin_blind: pallas::Base,
+    pub input_value: u64,
+    pub input_value_blind: pallas::Scalar,
+    pub hook_dao_exec: pallas::Base,
+    pub signature_secret: SecretKey,
+}
+
+impl Builder {
+    pub fn build(
+        self,
+        // zk_bins: &ZkContractTable
+    )
+    //-> FuncCall
+    {
+        debug!(target: "dao_contract::exec::wallet::Builder", "build()");
+        //let mut proofs = vec![];
+
+        let (proposal_dest_x, proposal_dest_y) = self.proposal.dest.xy();
+
+        let proposal_amount = pallas::Base::from(self.proposal.amount);
+
+        let dao_proposer_limit = pallas::Base::from(self.dao.proposer_limit);
+        let dao_quorum = pallas::Base::from(self.dao.quorum);
+        let dao_approval_ratio_quot = pallas::Base::from(self.dao.approval_ratio_quot);
+        let dao_approval_ratio_base = pallas::Base::from(self.dao.approval_ratio_base);
+
+        let (dao_pub_x, dao_pub_y) = self.dao.public_key.xy();
+
+        let user_spend_hook = pallas::Base::from(0);
+        let user_data = pallas::Base::from(0);
+        let input_value = pallas::Base::from(self.input_value);
+        let change = input_value - proposal_amount;
+
+        let dao_bulla = poseidon_hash::<8>([
+            dao_proposer_limit,
+            dao_quorum,
+            dao_approval_ratio_quot,
+            dao_approval_ratio_base,
+            self.dao.gov_token_id.inner(),
+            dao_pub_x,
+            dao_pub_y,
+            self.dao.bulla_blind,
+        ]);
+
+        let proposal_bulla = poseidon_hash::<8>([
+            proposal_dest_x,
+            proposal_dest_y,
+            proposal_amount,
+            self.proposal.serial,
+            self.proposal.token_id.inner(),
+            dao_bulla,
+            self.proposal.blind,
+            // @tmp-workaround
+            self.proposal.blind,
+        ]);
+
+        let coin_0 = poseidon_hash::<8>([
+            proposal_dest_x,
+            proposal_dest_y,
+            proposal_amount,
+            self.proposal.token_id.inner(),
+            self.proposal.serial,
+            user_spend_hook,
+            user_data,
+            self.proposal.blind,
+        ]);
+
+        let coin_1 = poseidon_hash::<8>([
+            dao_pub_x,
+            dao_pub_y,
+            change,
+            self.proposal.token_id.inner(),
+            self.dao_serial,
+            self.hook_dao_exec,
+            dao_bulla,
+            self.dao_coin_blind,
+        ]);
+
+        let yes_votes_commit = pedersen_commitment_u64(self.yes_votes_value, self.yes_votes_blind);
+        let yes_votes_commit_coords = yes_votes_commit.to_affine().coordinates().unwrap();
+
+        let all_votes_commit = pedersen_commitment_u64(self.all_votes_value, self.all_votes_blind);
+        let all_votes_commit_coords = all_votes_commit.to_affine().coordinates().unwrap();
+
+        let input_value_commit = pedersen_commitment_u64(self.input_value, self.input_value_blind);
+        let input_value_commit_coords = input_value_commit.to_affine().coordinates().unwrap();
+
+        /*
+        let zk_info = zk_bins.lookup(&"dao-exec".to_string()).unwrap();
+        let zk_info = if let ZkContractInfo::Binary(info) = zk_info {
+            info
+        } else {
+            panic!("Not binary info")
+        };
+
+        let zk_bin = zk_info.bincode.clone();
+        */
+
+        let prover_witnesses = vec![
+            //
+            // proposal params
+            Witness::Base(Value::known(proposal_dest_x)),
+            Witness::Base(Value::known(proposal_dest_y)),
+            Witness::Base(Value::known(proposal_amount)),
+            Witness::Base(Value::known(self.proposal.serial)),
+            Witness::Base(Value::known(self.proposal.token_id.inner())),
+            Witness::Base(Value::known(self.proposal.blind)),
+            // DAO params
+            Witness::Base(Value::known(dao_proposer_limit)),
+            Witness::Base(Value::known(dao_quorum)),
+            Witness::Base(Value::known(dao_approval_ratio_quot)),
+            Witness::Base(Value::known(dao_approval_ratio_base)),
+            Witness::Base(Value::known(self.dao.gov_token_id.inner())),
+            Witness::Base(Value::known(dao_pub_x)),
+            Witness::Base(Value::known(dao_pub_y)),
+            Witness::Base(Value::known(self.dao.bulla_blind)),
+            // votes
+            Witness::Base(Value::known(pallas::Base::from(self.yes_votes_value))),
+            Witness::Base(Value::known(pallas::Base::from(self.all_votes_value))),
+            Witness::Scalar(Value::known(self.yes_votes_blind)),
+            Witness::Scalar(Value::known(self.all_votes_blind)),
+            // outputs + inputs
+            Witness::Base(Value::known(self.user_serial)),
+            Witness::Base(Value::known(self.user_coin_blind)),
+            Witness::Base(Value::known(self.dao_serial)),
+            Witness::Base(Value::known(self.dao_coin_blind)),
+            Witness::Base(Value::known(input_value)),
+            Witness::Scalar(Value::known(self.input_value_blind)),
+            // misc
+            Witness::Base(Value::known(self.hook_dao_exec)),
+            Witness::Base(Value::known(user_spend_hook)),
+            Witness::Base(Value::known(user_data)),
+        ];
+
+        let public_inputs = vec![
+            proposal_bulla,
+            coin_0,
+            coin_1,
+            *yes_votes_commit_coords.x(),
+            *yes_votes_commit_coords.y(),
+            *all_votes_commit_coords.x(),
+            *all_votes_commit_coords.y(),
+            *input_value_commit_coords.x(),
+            *input_value_commit_coords.y(),
+            self.hook_dao_exec,
+            user_spend_hook,
+            user_data,
+        ];
+
+        /*
+        let circuit = ZkCircuit::new(prover_witnesses, zk_bin);
+        let proving_key = &zk_info.proving_key;
+        let input_proof = Proof::create(proving_key, &[circuit], &public_inputs, &mut OsRng)
+            .expect("DAO::exec() proving error!)");
+        proofs.push(input_proof);
+        */
+
+        /*
+        let call_data = CallData {
+            proposal: proposal_bulla,
+            coin_0,
+            coin_1,
+            yes_votes_commit,
+            all_votes_commit,
+            input_value_commit,
+        };
+
+        FuncCall {
+            contract_id: *CONTRACT_ID,
+            func_id: *super::FUNC_ID,
+            call_data: Box::new(call_data),
+            proofs,
+        }
+        */
+    }
+}

+ 4 - 0
src/contract/dao/src/lib.rs

@@ -38,6 +38,10 @@ pub mod dao_propose_client;
 /// Transaction building API for clients interacting with DAO contract
 pub mod dao_vote_client;
 
+#[cfg(feature = "client")]
+/// Transaction building API for clients interacting with DAO contract
+pub mod dao_exec_client;
+
 #[cfg(feature = "client")]
 /// Transaction building API for clients interacting with money contract
 pub mod money_client;

+ 24 - 24
src/contract/dao/tests/integration.rs

@@ -40,7 +40,7 @@ use rand::rngs::OsRng;
 
 use darkfi_dao_contract::{
     dao_client::{build_dao_mint_tx, MerkleTree, WalletCache},
-    dao_propose_client, dao_vote_client, money_client, note, DaoFunction,
+    dao_exec_client, dao_propose_client, dao_vote_client, money_client, note, DaoFunction,
 };
 
 use darkfi_money_contract::{
@@ -853,29 +853,29 @@ async fn integration_test() -> Result<()> {
             },
         ],
     };
-    //let (xfer_params, xfer_proofs) = builder.build(
-    //    &dao_th.dao_propose_burn_zkbin,
-    //    &dao_th.dao_propose_burn_pk,
-    //    &dao_th.dao_propose_main_zkbin,
-    //    &dao_th.dao_propose_main_pk,
-    //)?;
-
-    //let builder = dao::exec::wallet::Builder {
-    //    proposal,
-    //    dao: dao_params.clone(),
-    //    yes_votes_value,
-    //    all_votes_value,
-    //    yes_votes_blind,
-    //    all_votes_blind,
-    //    user_serial,
-    //    user_coin_blind,
-    //    dao_serial,
-    //    dao_coin_blind,
-    //    input_value,
-    //    input_value_blind,
-    //    hook_dao_exec: *dao::exec::FUNC_ID,
-    //    signature_secret: exec_signature_secret,
-    //};
+    let (xfer_params, xfer_proofs) = builder.build(
+        &dao_th.money_mint_zkbin,
+        &dao_th.money_mint_pk,
+        &dao_th.money_burn_zkbin,
+        &dao_th.money_burn_pk,
+    )?;
+
+    let builder = dao_exec_client::Builder {
+        proposal,
+        dao: dao_params.clone(),
+        yes_votes_value,
+        all_votes_value,
+        yes_votes_blind,
+        all_votes_blind,
+        user_serial,
+        user_coin_blind,
+        dao_serial,
+        dao_coin_blind,
+        input_value,
+        input_value_blind,
+        hook_dao_exec: spend_hook,
+        signature_secret: exec_signature_secret,
+    };
 
     Ok(())
 }