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

This commit is contained in:
skoupidi
2024-05-20 15:14:13 +03:00
parent 0fb90b0978
commit e93b6cca95
6 changed files with 80 additions and 26 deletions

View File

@@ -29,10 +29,13 @@ use rand::rngs::OsRng;
use darkfi::{
zk::{halo2::Value, Proof, ProvingKey, Witness, ZkCircuit},
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 proposal: DaoProposal,
@@ -54,7 +57,7 @@ impl DaoExecCall {
exec_zkbin: &ZkBinary,
exec_pk: &ProvingKey,
) -> Result<(DaoExecParams, Vec<Proof>)> {
debug!(target: "dao", "build()");
debug!(target: "contract::dao::client::exec", "build()");
let mut proofs = vec![];
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_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 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())),
];
debug!(target: "dao", "proposal_bulla: {:?}", proposal_bulla);
debug!(target: "contract::dao::client::exec", "proposal_bulla: {:?}", proposal_bulla);
let public_inputs = vec![
proposal_bulla.inner(),
proposal_auth_calls_commit,

View File

@@ -49,7 +49,7 @@ pub fn make_mint_call(
dao_mint_zkbin: &ZkBinary,
dao_mint_pk: &ProvingKey,
) -> 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_quorum = pallas::Base::from(dao.quorum);

View File

@@ -32,10 +32,13 @@ use rand::rngs::OsRng;
use darkfi::{
zk::{halo2::Value, Proof, ProvingKey, Witness, ZkCircuit},
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 secret: SecretKey,
@@ -96,7 +99,11 @@ impl<'a> DaoProposeCall<'a> {
let smt_null_root = input.money_null_smt.root();
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![
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()]);
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_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();
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 prover_witnesses = vec![

View File

@@ -33,10 +33,13 @@ use rand::rngs::OsRng;
use darkfi::{
zk::{halo2::Value, Proof, ProvingKey, Witness, ZkCircuit},
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 secret: SecretKey,
@@ -65,9 +68,11 @@ impl<'a> DaoVoteCall<'a> {
main_zkbin: &ZkBinary,
main_pk: &ProvingKey,
) -> 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 mut proofs = vec![];
@@ -125,7 +130,11 @@ impl<'a> DaoVoteCall<'a> {
let smt_null_root = self.money_null_smt.root();
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![
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]);
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_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 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 ∈ 𝔽ₚ
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 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();
// Convert blinds to 𝔽ₚ, which should work fine since we selected them

View File

@@ -17,6 +17,7 @@
*/
use darkfi_money_contract::{
error::MoneyError,
model::{Coin, MoneyTransferParamsV1},
MoneyFunction,
};
@@ -54,8 +55,15 @@ pub(crate) fn dao_authxfer_get_metadata(
let exec_callnode = &calls[parent_idx];
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 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..])?;
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
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.
// We check this by ensuring that user_data_enc is also the same for all inputs.

View File

@@ -17,8 +17,9 @@
*/
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::{
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())
}
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 = TransactionHash(tx_hash_data);
// Get block_height where tx_hash was confirmed