فهرست منبع

contract/dao/{entrypoint, client}: replaced asserts with error returns and fixed log targets

skoupidi 2 سال پیش
والد
کامیت
e93b6cca95

+ 10 - 5
src/contract/dao/src/client/exec.rs

@@ -29,10 +29,13 @@ use rand::rngs::OsRng;
 use darkfi::{
 use darkfi::{
     zk::{halo2::Value, Proof, ProvingKey, Witness, ZkCircuit},
     zk::{halo2::Value, Proof, ProvingKey, Witness, ZkCircuit},
     zkas::ZkBinary,
     zkas::ZkBinary,
-    Result,
+    ClientFailed, Result,
 };
 };
 
 
-use crate::model::{Dao, DaoBlindAggregateVote, DaoExecParams, DaoProposal, VecAuthCallCommit};
+use crate::{
+    error::DaoError,
+    model::{Dao, DaoBlindAggregateVote, DaoExecParams, DaoProposal, VecAuthCallCommit},
+};
 
 
 pub struct DaoExecCall {
 pub struct DaoExecCall {
     pub proposal: DaoProposal,
     pub proposal: DaoProposal,
@@ -54,7 +57,7 @@ impl DaoExecCall {
         exec_zkbin: &ZkBinary,
         exec_zkbin: &ZkBinary,
         exec_pk: &ProvingKey,
         exec_pk: &ProvingKey,
     ) -> Result<(DaoExecParams, Vec<Proof>)> {
     ) -> Result<(DaoExecParams, Vec<Proof>)> {
-        debug!(target: "dao", "build()");
+        debug!(target: "contract::dao::client::exec", "build()");
         let mut proofs = vec![];
         let mut proofs = vec![];
 
 
         let dao_proposer_limit = pallas::Base::from(self.dao.proposer_limit);
         let dao_proposer_limit = pallas::Base::from(self.dao.proposer_limit);
@@ -65,7 +68,9 @@ impl DaoExecCall {
         let (dao_pub_x, dao_pub_y) = self.dao.public_key.xy();
         let (dao_pub_x, dao_pub_y) = self.dao.public_key.xy();
 
 
         let dao_bulla = self.dao.to_bulla();
         let dao_bulla = self.dao.to_bulla();
-        assert_eq!(dao_bulla, self.proposal.dao_bulla);
+        if dao_bulla != self.proposal.dao_bulla {
+            return Err(ClientFailed::VerifyError(DaoError::InvalidCalls.to_string()).into())
+        }
         let proposal_bulla = self.proposal.to_bulla();
         let proposal_bulla = self.proposal.to_bulla();
 
 
         let yes_vote_commit = pedersen_commitment_u64(self.yes_vote_value, self.yes_vote_blind);
         let yes_vote_commit = pedersen_commitment_u64(self.yes_vote_value, self.yes_vote_blind);
@@ -103,7 +108,7 @@ impl DaoExecCall {
             Witness::Base(Value::known(self.signature_secret.inner())),
             Witness::Base(Value::known(self.signature_secret.inner())),
         ];
         ];
 
 
-        debug!(target: "dao", "proposal_bulla: {:?}", proposal_bulla);
+        debug!(target: "contract::dao::client::exec", "proposal_bulla: {:?}", proposal_bulla);
         let public_inputs = vec![
         let public_inputs = vec![
             proposal_bulla.inner(),
             proposal_bulla.inner(),
             proposal_auth_calls_commit,
             proposal_auth_calls_commit,

+ 1 - 1
src/contract/dao/src/client/mint.rs

@@ -49,7 +49,7 @@ pub fn make_mint_call(
     dao_mint_zkbin: &ZkBinary,
     dao_mint_zkbin: &ZkBinary,
     dao_mint_pk: &ProvingKey,
     dao_mint_pk: &ProvingKey,
 ) -> Result<(DaoMintParams, Vec<Proof>)> {
 ) -> Result<(DaoMintParams, Vec<Proof>)> {
-    debug!(target: "dao", "Building DAO contract mint transaction");
+    debug!(target: "contract::dao::client::mint", "Building DAO contract mint transaction");
 
 
     let dao_proposer_limit = pallas::Base::from(dao.proposer_limit);
     let dao_proposer_limit = pallas::Base::from(dao.proposer_limit);
     let dao_quorum = pallas::Base::from(dao.quorum);
     let dao_quorum = pallas::Base::from(dao.quorum);

+ 16 - 5
src/contract/dao/src/client/propose.rs

@@ -32,10 +32,13 @@ use rand::rngs::OsRng;
 use darkfi::{
 use darkfi::{
     zk::{halo2::Value, Proof, ProvingKey, Witness, ZkCircuit},
     zk::{halo2::Value, Proof, ProvingKey, Witness, ZkCircuit},
     zkas::ZkBinary,
     zkas::ZkBinary,
-    Result,
+    ClientFailed, Result,
 };
 };
 
 
-use crate::model::{Dao, DaoProposal, DaoProposeParams, DaoProposeParamsInput, VecAuthCallCommit};
+use crate::{
+    error::DaoError,
+    model::{Dao, DaoProposal, DaoProposeParams, DaoProposeParamsInput, VecAuthCallCommit},
+};
 
 
 pub struct DaoProposeStakeInput<'a> {
 pub struct DaoProposeStakeInput<'a> {
     pub secret: SecretKey,
     pub secret: SecretKey,
@@ -96,7 +99,11 @@ impl<'a> DaoProposeCall<'a> {
 
 
             let smt_null_root = input.money_null_smt.root();
             let smt_null_root = input.money_null_smt.root();
             let smt_null_path = input.money_null_smt.prove_membership(&nullifier);
             let smt_null_path = input.money_null_smt.prove_membership(&nullifier);
-            assert!(smt_null_path.verify(&smt_null_root, &pallas::Base::ZERO, &nullifier));
+            if !smt_null_path.verify(&smt_null_root, &pallas::Base::ZERO, &nullifier) {
+                return Err(
+                    ClientFailed::VerifyError(DaoError::InvalidInputMerkleRoot.to_string()).into()
+                )
+            }
 
 
             let prover_witnesses = vec![
             let prover_witnesses = vec![
                 Witness::Base(Value::known(input.secret.inner())),
                 Witness::Base(Value::known(input.secret.inner())),
@@ -130,7 +137,9 @@ impl<'a> DaoProposeCall<'a> {
             };
             };
 
 
             let token_commit = poseidon_hash([note.token_id.inner(), gov_token_blind.inner()]);
             let token_commit = poseidon_hash([note.token_id.inner(), gov_token_blind.inner()]);
-            assert_eq!(self.dao.gov_token_id, note.token_id);
+            if note.token_id != self.dao.gov_token_id {
+                return Err(ClientFailed::InvalidTokenId(note.token_id.to_string()).into())
+            }
 
 
             let value_commit = pedersen_commitment_u64(note.value, funds_blind);
             let value_commit = pedersen_commitment_u64(note.value, funds_blind);
             let value_coords = value_commit.to_affine().coordinates().unwrap();
             let value_coords = value_commit.to_affine().coordinates().unwrap();
@@ -176,7 +185,9 @@ impl<'a> DaoProposeCall<'a> {
 
 
         let dao_leaf_position: u64 = self.dao_leaf_position.into();
         let dao_leaf_position: u64 = self.dao_leaf_position.into();
 
 
-        assert_eq!(self.dao.to_bulla(), self.proposal.dao_bulla);
+        if self.dao.to_bulla() != self.proposal.dao_bulla {
+            return Err(ClientFailed::VerifyError(DaoError::InvalidCalls.to_string()).into())
+        }
         let proposal_bulla = self.proposal.to_bulla();
         let proposal_bulla = self.proposal.to_bulla();
 
 
         let prover_witnesses = vec![
         let prover_witnesses = vec![

+ 23 - 8
src/contract/dao/src/client/vote.rs

@@ -33,10 +33,13 @@ use rand::rngs::OsRng;
 use darkfi::{
 use darkfi::{
     zk::{halo2::Value, Proof, ProvingKey, Witness, ZkCircuit},
     zk::{halo2::Value, Proof, ProvingKey, Witness, ZkCircuit},
     zkas::ZkBinary,
     zkas::ZkBinary,
-    Result,
+    ClientFailed, Result,
 };
 };
 
 
-use crate::model::{Dao, DaoProposal, DaoVoteParams, DaoVoteParamsInput, VecAuthCallCommit};
+use crate::{
+    error::DaoError,
+    model::{Dao, DaoProposal, DaoVoteParams, DaoVoteParamsInput, VecAuthCallCommit},
+};
 
 
 pub struct DaoVoteInput {
 pub struct DaoVoteInput {
     pub secret: SecretKey,
     pub secret: SecretKey,
@@ -65,9 +68,11 @@ impl<'a> DaoVoteCall<'a> {
         main_zkbin: &ZkBinary,
         main_zkbin: &ZkBinary,
         main_pk: &ProvingKey,
         main_pk: &ProvingKey,
     ) -> Result<(DaoVoteParams, Vec<Proof>)> {
     ) -> Result<(DaoVoteParams, Vec<Proof>)> {
-        debug!(target: "dao", "build()");
+        debug!(target: "contract::dao::client::vote", "build()");
 
 
-        assert_eq!(self.dao.to_bulla(), self.proposal.dao_bulla);
+        if self.dao.to_bulla() != self.proposal.dao_bulla {
+            return Err(ClientFailed::VerifyError(DaoError::InvalidCalls.to_string()).into())
+        }
         let proposal_bulla = self.proposal.to_bulla();
         let proposal_bulla = self.proposal.to_bulla();
 
 
         let mut proofs = vec![];
         let mut proofs = vec![];
@@ -125,7 +130,11 @@ impl<'a> DaoVoteCall<'a> {
 
 
             let smt_null_root = self.money_null_smt.root();
             let smt_null_root = self.money_null_smt.root();
             let smt_null_path = self.money_null_smt.prove_membership(&nullifier);
             let smt_null_path = self.money_null_smt.prove_membership(&nullifier);
-            assert!(smt_null_path.verify(&smt_null_root, &pallas::Base::ZERO, &nullifier));
+            if !smt_null_path.verify(&smt_null_root, &pallas::Base::ZERO, &nullifier) {
+                return Err(
+                    ClientFailed::VerifyError(DaoError::InvalidInputMerkleRoot.to_string()).into()
+                )
+            }
 
 
             let prover_witnesses = vec![
             let prover_witnesses = vec![
                 Witness::Base(Value::known(input.secret.inner())),
                 Witness::Base(Value::known(input.secret.inner())),
@@ -158,7 +167,9 @@ impl<'a> DaoVoteCall<'a> {
             };
             };
 
 
             let token_commit = poseidon_hash([note.token_id.inner(), gov_token_blind]);
             let token_commit = poseidon_hash([note.token_id.inner(), gov_token_blind]);
-            assert_eq!(self.dao.gov_token_id, note.token_id);
+            if note.token_id != self.dao.gov_token_id {
+                return Err(ClientFailed::InvalidTokenId(note.token_id.to_string()).into())
+            }
 
 
             let vote_commit = pedersen_commitment_u64(note.value, Blind(value_blind));
             let vote_commit = pedersen_commitment_u64(note.value, Blind(value_blind));
             let vote_commit_coords = vote_commit.to_affine().coordinates().unwrap();
             let vote_commit_coords = vote_commit.to_affine().coordinates().unwrap();
@@ -203,7 +214,9 @@ impl<'a> DaoVoteCall<'a> {
         let dao_public_key = self.dao.public_key.inner();
         let dao_public_key = self.dao.public_key.inner();
 
 
         let vote_option = self.vote_option as u64;
         let vote_option = self.vote_option as u64;
-        assert!(vote_option == 0 || vote_option == 1);
+        if vote_option != 0 && vote_option != 1 {
+            return Err(ClientFailed::VerifyError(DaoError::VoteInputsEmpty.to_string()).into())
+        }
 
 
         // Create a random blind b ∈ 𝔽ᵥ, such that b ∈ 𝔽ₚ
         // Create a random blind b ∈ 𝔽ᵥ, such that b ∈ 𝔽ₚ
         let yes_vote_blind = loop {
         let yes_vote_blind = loop {
@@ -217,7 +230,9 @@ impl<'a> DaoVoteCall<'a> {
         let yes_vote_commit_coords = yes_vote_commit.to_affine().coordinates().unwrap();
         let yes_vote_commit_coords = yes_vote_commit.to_affine().coordinates().unwrap();
 
 
         let all_vote_commit = pedersen_commitment_u64(all_vote_value, Blind(all_vote_blind));
         let all_vote_commit = pedersen_commitment_u64(all_vote_value, Blind(all_vote_blind));
-        assert_eq!(all_vote_commit, inputs.iter().map(|i| i.vote_commit).sum());
+        if all_vote_commit != inputs.iter().map(|i| i.vote_commit).sum() {
+            return Err(ClientFailed::VerifyError(DaoError::VoteCommitMismatch.to_string()).into())
+        }
         let all_vote_commit_coords = all_vote_commit.to_affine().coordinates().unwrap();
         let all_vote_commit_coords = all_vote_commit.to_affine().coordinates().unwrap();
 
 
         // Convert blinds to 𝔽ₚ, which should work fine since we selected them
         // Convert blinds to 𝔽ₚ, which should work fine since we selected them

+ 19 - 4
src/contract/dao/src/entrypoint/auth_xfer.rs

@@ -17,6 +17,7 @@
  */
  */
 
 
 use darkfi_money_contract::{
 use darkfi_money_contract::{
+    error::MoneyError,
     model::{Coin, MoneyTransferParamsV1},
     model::{Coin, MoneyTransferParamsV1},
     MoneyFunction,
     MoneyFunction,
 };
 };
@@ -54,8 +55,15 @@ pub(crate) fn dao_authxfer_get_metadata(
     let exec_callnode = &calls[parent_idx];
     let exec_callnode = &calls[parent_idx];
     let exec_params: DaoExecParams = deserialize(&exec_callnode.data.data[1..])?;
     let exec_params: DaoExecParams = deserialize(&exec_callnode.data.data[1..])?;
 
 
-    assert!(!xfer_params.inputs.is_empty());
-    assert!(!xfer_params.outputs.is_empty());
+    if xfer_params.inputs.is_empty() {
+        msg!("[Dao::AuthXfer] Error: Transfer inputs are missing");
+        return Err(MoneyError::TransferMissingInputs.into())
+    }
+
+    if xfer_params.outputs.len() <= 1 {
+        msg!("[Dao::AuthXfer] Error: Transfer outputs are missing");
+        return Err(MoneyError::TransferMissingOutputs.into())
+    }
 
 
     let mut zk_public_inputs: Vec<(String, Vec<pallas::Base>)> = vec![];
     let mut zk_public_inputs: Vec<(String, Vec<pallas::Base>)> = vec![];
     let signature_pubkeys: Vec<PublicKey> = vec![];
     let signature_pubkeys: Vec<PublicKey> = vec![];
@@ -153,9 +161,16 @@ pub(crate) fn dao_authxfer_process_instruction(
     ///////////////////////////////////////////////////
     ///////////////////////////////////////////////////
 
 
     let xfer_params: MoneyTransferParamsV1 = deserialize(&xfer_call.data[1..])?;
     let xfer_params: MoneyTransferParamsV1 = deserialize(&xfer_call.data[1..])?;
-    assert!(!xfer_params.inputs.is_empty());
+    if xfer_params.inputs.is_empty() {
+        msg!("[Dao::AuthXfer] Error: Transfer inputs are missing");
+        return Err(MoneyError::TransferMissingInputs.into())
+    }
+
     // We need the last output to be the change
     // We need the last output to be the change
-    assert!(xfer_params.outputs.len() > 1);
+    if xfer_params.outputs.len() <= 1 {
+        msg!("[Dao::AuthXfer] Error: Transfer outputs are missing");
+        return Err(MoneyError::TransferMissingOutputs.into())
+    }
 
 
     // MoneyTransfer should all have the same user_data set.
     // MoneyTransfer should all have the same user_data set.
     // We check this by ensuring that user_data_enc is also the same for all inputs.
     // We check this by ensuring that user_data_enc is also the same for all inputs.

+ 11 - 3
src/contract/dao/src/entrypoint/propose.rs

@@ -17,8 +17,9 @@
  */
  */
 
 
 use darkfi_money_contract::{
 use darkfi_money_contract::{
-    MONEY_CONTRACT_COIN_ROOTS_TREE, MONEY_CONTRACT_INFO_TREE, MONEY_CONTRACT_LATEST_COIN_ROOT,
-    MONEY_CONTRACT_LATEST_NULLIFIER_ROOT, MONEY_CONTRACT_NULLIFIER_ROOTS_TREE,
+    error::MoneyError, MONEY_CONTRACT_COIN_ROOTS_TREE, MONEY_CONTRACT_INFO_TREE,
+    MONEY_CONTRACT_LATEST_COIN_ROOT, MONEY_CONTRACT_LATEST_NULLIFIER_ROOT,
+    MONEY_CONTRACT_NULLIFIER_ROOTS_TREE,
 };
 };
 use darkfi_sdk::{
 use darkfi_sdk::{
     crypto::{contract_id::MONEY_CONTRACT_ID, pasta_prelude::*, ContractId, MerkleNode, PublicKey},
     crypto::{contract_id::MONEY_CONTRACT_ID, pasta_prelude::*, ContractId, MerkleNode, PublicKey},
@@ -149,7 +150,14 @@ pub(crate) fn dao_propose_process_instruction(
             return Err(DaoError::NonMatchingSnapshotRoots.into())
             return Err(DaoError::NonMatchingSnapshotRoots.into())
         }
         }
 
 
-        assert_eq!(coin_root_data.len(), 32 + 1);
+        if coin_root_data.len() != 32 + 1 {
+            msg!(
+                "[Dao::Propose] Error: Coin roots data length is not expected(32 + 1): {}",
+                coin_root_data.len()
+            );
+            return Err(MoneyError::RootsValueDataMismatch.into())
+        }
+
         let tx_hash_data: [u8; 32] = coin_root_data[0..32].try_into().unwrap();
         let tx_hash_data: [u8; 32] = coin_root_data[0..32].try_into().unwrap();
         let tx_hash = TransactionHash(tx_hash_data);
         let tx_hash = TransactionHash(tx_hash_data);
         // Get block_height where tx_hash was confirmed
         // Get block_height where tx_hash was confirmed