diff --git a/src/contract/dao/proof/dao-exec.zk b/src/contract/dao/proof/dao-exec.zk index aff3dea29..2944a987b 100644 --- a/src/contract/dao/proof/dao-exec.zk +++ b/src/contract/dao/proof/dao-exec.zk @@ -23,10 +23,10 @@ contract "DaoExec" { Base dao_bulla_blind, # Votes - Base yes_votes_value, - Base all_votes_value, - Scalar yes_votes_blind, - Scalar all_votes_blind, + Base yes_vote_value, + Base all_vote_value, + Scalar yes_vote_blind, + Scalar all_vote_blind, # Outputs + Inputs Base user_serial, @@ -98,17 +98,17 @@ circuit "DaoExec" { # Create Pedersen commitments for win_votes and total_votes, and # constrain the commitments' coordinates. - yes_votes_value_c = ec_mul_short(yes_votes_value, VALUE_COMMIT_VALUE); - yes_votes_blind_c = ec_mul(yes_votes_blind, VALUE_COMMIT_RANDOM); - yes_votes_commit = ec_add(yes_votes_value_c, yes_votes_blind_c); - constrain_instance(ec_get_x(yes_votes_commit)); - constrain_instance(ec_get_y(yes_votes_commit)); + yes_vote_value_c = ec_mul_short(yes_vote_value, VALUE_COMMIT_VALUE); + yes_vote_blind_c = ec_mul(yes_vote_blind, VALUE_COMMIT_RANDOM); + yes_vote_commit = ec_add(yes_vote_value_c, yes_vote_blind_c); + constrain_instance(ec_get_x(yes_vote_commit)); + constrain_instance(ec_get_y(yes_vote_commit)); - all_votes_value_c = ec_mul_short(all_votes_value, VALUE_COMMIT_VALUE); - all_votes_blind_c = ec_mul(all_votes_blind, VALUE_COMMIT_RANDOM); - all_votes_commit = ec_add(all_votes_value_c, all_votes_blind_c); - constrain_instance(ec_get_x(all_votes_commit)); - constrain_instance(ec_get_y(all_votes_commit)); + all_vote_value_c = ec_mul_short(all_vote_value, VALUE_COMMIT_VALUE); + all_vote_blind_c = ec_mul(all_vote_blind, VALUE_COMMIT_RANDOM); + all_vote_commit = ec_add(all_vote_value_c, all_vote_blind_c); + constrain_instance(ec_get_x(all_vote_commit)); + constrain_instance(ec_get_y(all_vote_commit)); # Create Pedersen commitment for input_value and make public input_value_v = ec_mul_short(input_value, VALUE_COMMIT_VALUE); @@ -121,18 +121,18 @@ circuit "DaoExec" { constrain_instance(user_spend_hook); constrain_instance(user_data); - # Check that dao_quorum is less than or equal to all_votes_value + # Check that dao_quorum is less than or equal to all_vote_value one = witness_base(1); - all_votes_value_1 = base_add(all_votes_value, one); - less_than_strict(dao_quorum, all_votes_value_1); + all_vote_value_1 = base_add(all_vote_value, one); + less_than_strict(dao_quorum, all_vote_value_1); - # approval_ratio_quot / approval_ratio_base <= yes_votes / all_votes + # approval_ratio_quot / approval_ratio_base <= yes_vote / all_vote # # The above is also equivalent to this: # - # all_votes * approval_ratio_quot <= yes_votes * approval_ratio_base - lhs = base_mul(all_votes_value, dao_approval_ratio_quot); - rhs = base_mul(yes_votes_value, dao_approval_ratio_base); + # all_vote * approval_ratio_quot <= yes_vote * approval_ratio_base + lhs = base_mul(all_vote_value, dao_approval_ratio_quot); + rhs = base_mul(yes_vote_value, dao_approval_ratio_base); rhs_1 = base_add(rhs, one); less_than_strict(lhs, rhs_1); diff --git a/src/contract/dao/proof/dao-vote-main.zk b/src/contract/dao/proof/dao-vote-main.zk index 22b56fd1a..c1871d75b 100644 --- a/src/contract/dao/proof/dao-vote-main.zk +++ b/src/contract/dao/proof/dao-vote-main.zk @@ -27,8 +27,8 @@ contract "DaoVoteMain" { Scalar yes_vote_blind, # Total amount of capital allocated to vote - Base all_votes_value, - Scalar all_votes_blind, + Base all_vote_value, + Scalar all_vote_blind, # Check the inputs and this proof are for the same token Base gov_token_blind, @@ -65,19 +65,19 @@ circuit "DaoVoteMain" { # Normally we call this yes vote # Pedersen commitment for vote option - yes_votes_value = base_mul(vote_option, all_votes_value); - yes_votes_value_c = ec_mul_short(yes_votes_value, VALUE_COMMIT_VALUE); - yes_votes_blind_c = ec_mul(yes_vote_blind, VALUE_COMMIT_RANDOM); - yes_votes_commit = ec_add(yes_votes_value_c, yes_votes_blind_c); - constrain_instance(ec_get_x(yes_votes_commit)); - constrain_instance(ec_get_y(yes_votes_commit)); + yes_vote_value = base_mul(vote_option, all_vote_value); + yes_vote_value_c = ec_mul_short(yes_vote_value, VALUE_COMMIT_VALUE); + yes_vote_blind_c = ec_mul(yes_vote_blind, VALUE_COMMIT_RANDOM); + yes_vote_commit = ec_add(yes_vote_value_c, yes_vote_blind_c); + constrain_instance(ec_get_x(yes_vote_commit)); + constrain_instance(ec_get_y(yes_vote_commit)); # Pedersen commitment for vote value - all_votes_c = ec_mul_short(all_votes_value, VALUE_COMMIT_VALUE); - all_votes_blind_c = ec_mul(all_votes_blind, VALUE_COMMIT_RANDOM); - all_votes_commit = ec_add(all_votes_c, all_votes_blind_c); - constrain_instance(ec_get_x(all_votes_commit)); - constrain_instance(ec_get_y(all_votes_commit)); + all_vote_c = ec_mul_short(all_vote_value, VALUE_COMMIT_VALUE); + all_vote_blind_c = ec_mul(all_vote_blind, VALUE_COMMIT_RANDOM); + all_vote_commit = ec_add(all_vote_c, all_vote_blind_c); + constrain_instance(ec_get_x(all_vote_commit)); + constrain_instance(ec_get_y(all_vote_commit)); # Vote option should be 0 or 1 bool_check(vote_option); diff --git a/src/contract/dao/src/dao_client/exec.rs b/src/contract/dao/src/dao_client/exec.rs index ba94136ad..4517286b8 100644 --- a/src/contract/dao/src/dao_client/exec.rs +++ b/src/contract/dao/src/dao_client/exec.rs @@ -31,15 +31,15 @@ use darkfi::{ }; use super::{DaoInfo, ProposalInfo}; -use crate::dao_model::ExecCallParams; +use crate::dao_model::{BlindAggregateVote, ExecCallParams}; pub struct ExecCall { pub proposal: ProposalInfo, pub dao: DaoInfo, - pub yes_votes_value: u64, - pub all_votes_value: u64, - pub yes_votes_blind: pallas::Scalar, - pub all_votes_blind: pallas::Scalar, + pub yes_vote_value: u64, + pub all_vote_value: u64, + pub yes_vote_blind: pallas::Scalar, + pub all_vote_blind: pallas::Scalar, pub user_serial: pallas::Base, pub user_coin_blind: pallas::Base, pub dao_serial: pallas::Base, @@ -120,11 +120,11 @@ impl ExecCall { 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 yes_vote_commit = pedersen_commitment_u64(self.yes_vote_value, self.yes_vote_blind); + let yes_vote_commit_coords = yes_vote_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 all_vote_commit = pedersen_commitment_u64(self.all_vote_value, self.all_vote_blind); + let all_vote_commit_coords = all_vote_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(); @@ -147,10 +147,10 @@ impl ExecCall { 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)), + Witness::Base(Value::known(pallas::Base::from(self.yes_vote_value))), + Witness::Base(Value::known(pallas::Base::from(self.all_vote_value))), + Witness::Scalar(Value::known(self.yes_vote_blind)), + Witness::Scalar(Value::known(self.all_vote_blind)), // outputs + inputs Witness::Base(Value::known(self.user_serial)), Witness::Base(Value::known(self.user_coin_blind)), @@ -169,10 +169,10 @@ impl ExecCall { 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(), + *yes_vote_commit_coords.x(), + *yes_vote_commit_coords.y(), + *all_vote_commit_coords.x(), + *all_vote_commit_coords.y(), *input_value_commit_coords.x(), *input_value_commit_coords.y(), self.hook_dao_exec, @@ -189,8 +189,7 @@ impl ExecCall { proposal: proposal_bulla, coin_0, coin_1, - yes_votes_commit, - all_votes_commit, + blind_total_vote: BlindAggregateVote { yes_vote_commit, all_vote_commit }, input_value_commit, }; diff --git a/src/contract/dao/src/dao_client/mod.rs b/src/contract/dao/src/dao_client/mod.rs index 38c60984a..07f4fc6d4 100644 --- a/src/contract/dao/src/dao_client/mod.rs +++ b/src/contract/dao/src/dao_client/mod.rs @@ -17,7 +17,7 @@ pub use propose::{ProposalInfo, ProposeCall, ProposeNote, ProposeStakeInput}; /// * `VoteCall` is what creates the call data used on chain. /// * `VoteNote` is the secret shared info transmitted between DAO members. pub mod vote; -pub use vote::{VoteCall, VoteInfo, VoteInput, VoteNote}; +pub use vote::{VoteCall, VoteInput, VoteNote}; pub mod exec; pub use exec::ExecCall; diff --git a/src/contract/dao/src/dao_client/vote.rs b/src/contract/dao/src/dao_client/vote.rs index cd185f10c..3842e0fdb 100644 --- a/src/contract/dao/src/dao_client/vote.rs +++ b/src/contract/dao/src/dao_client/vote.rs @@ -38,15 +38,11 @@ use crate::{ #[derive(SerialEncodable, SerialDecodable)] pub struct VoteNote { - pub vote: VoteInfo, - pub vote_value: u64, - pub vote_value_blind: pallas::Scalar, -} - -#[derive(SerialEncodable, SerialDecodable)] -pub struct VoteInfo { pub vote_option: bool, - pub vote_option_blind: pallas::Scalar, + pub yes_vote_blind: pallas::Scalar, + // yes_vote_value = vote_option * all_vote_value + pub all_vote_value: u64, + pub all_vote_blind: pallas::Scalar, } pub struct VoteInput { @@ -62,7 +58,8 @@ pub struct VoteInput { // Inside ZKproof, check proposal is correct. pub struct VoteCall { pub inputs: Vec, - pub vote: VoteInfo, + pub vote_option: bool, + pub yes_vote_blind: pallas::Scalar, pub vote_keypair: Keypair, pub proposal: ProposalInfo, pub dao: DaoInfo, @@ -82,14 +79,14 @@ impl VoteCall { let gov_token_blind = pallas::Base::random(&mut OsRng); let mut inputs = vec![]; - let mut vote_value = 0; - let mut vote_value_blind = pallas::Scalar::from(0); + let mut all_vote_value = 0; + let mut all_vote_blind = pallas::Scalar::from(0); for input in self.inputs { let value_blind = pallas::Scalar::random(&mut OsRng); - vote_value += input.note.value; - vote_value_blind += value_blind; + all_vote_value += input.note.value; + all_vote_blind += value_blind; let signature_public = PublicKey::from_secret(input.signature_secret); @@ -105,7 +102,7 @@ impl VoteCall { Witness::Base(halo2::Value::known(pallas::Base::from(note.value))), Witness::Base(halo2::Value::known(note.token_id.inner())), Witness::Base(halo2::Value::known(note.coin_blind)), - Witness::Scalar(halo2::Value::known(vote_value_blind)), + Witness::Scalar(halo2::Value::known(all_vote_blind)), Witness::Base(halo2::Value::known(gov_token_blind)), Witness::Uint32(halo2::Value::known(leaf_pos.try_into().unwrap())), Witness::MerklePath(halo2::Value::known( @@ -147,7 +144,7 @@ impl VoteCall { let nullifier = poseidon_hash::<2>([input.secret.inner(), note.serial]); - let vote_commit = pedersen_commitment_u64(note.value, vote_value_blind); + let vote_commit = pedersen_commitment_u64(note.value, all_vote_blind); let vote_commit_coords = vote_commit.to_affine().coordinates().unwrap(); let (sig_x, sig_y) = signature_public.xy(); @@ -213,14 +210,14 @@ impl VoteCall { self.proposal.blind, ]); - let vote_option = self.vote.vote_option as u64; + let vote_option = self.vote_option as u64; assert!(vote_option == 0 || vote_option == 1); let yes_vote_commit = - pedersen_commitment_u64(vote_option * vote_value, self.vote.vote_option_blind); + pedersen_commitment_u64(vote_option * all_vote_value, self.yes_vote_blind); let yes_vote_commit_coords = yes_vote_commit.to_affine().coordinates().unwrap(); - let all_vote_commit = pedersen_commitment_u64(vote_value, vote_value_blind); + let all_vote_commit = pedersen_commitment_u64(all_vote_value, all_vote_blind); let all_vote_commit_coords = all_vote_commit.to_affine().coordinates().unwrap(); let prover_witnesses = vec![ @@ -242,10 +239,10 @@ impl VoteCall { Witness::Base(halo2::Value::known(self.dao.bulla_blind)), // Vote Witness::Base(halo2::Value::known(pallas::Base::from(vote_option))), - Witness::Scalar(halo2::Value::known(self.vote.vote_option_blind)), + Witness::Scalar(halo2::Value::known(self.yes_vote_blind)), // Total number of gov tokens allocated - Witness::Base(halo2::Value::known(pallas::Base::from(vote_value))), - Witness::Scalar(halo2::Value::known(vote_value_blind)), + Witness::Base(halo2::Value::known(pallas::Base::from(all_vote_value))), + Witness::Scalar(halo2::Value::known(all_vote_blind)), // gov token Witness::Base(halo2::Value::known(gov_token_blind)), ]; @@ -267,14 +264,18 @@ impl VoteCall { .expect("DAO::vote() proving error!"); proofs.push(main_proof); - let note = VoteNote { vote: self.vote, vote_value, vote_value_blind }; + let note = VoteNote { + vote_option: self.vote_option, + yes_vote_blind: self.yes_vote_blind, + all_vote_value, + all_vote_blind, + }; let enc_note = note::encrypt(¬e, &self.vote_keypair.public).unwrap(); let params = VoteCallParams { token_commit, proposal_bulla, yes_vote_commit, - ciphertext: enc_note.ciphertext, ephem_public: enc_note.ephem_public, inputs, diff --git a/src/contract/dao/src/dao_model.rs b/src/contract/dao/src/dao_model.rs index 50b1f0613..6dea15693 100644 --- a/src/contract/dao/src/dao_model.rs +++ b/src/contract/dao/src/dao_model.rs @@ -101,27 +101,23 @@ pub struct VoteCallUpdate { #[derive(SerialEncodable, SerialDecodable)] pub struct BlindAggregateVote { /// Weighted vote commit - pub yes_votes_commit: pallas::Point, + pub yes_vote_commit: pallas::Point, /// All value staked in the vote - pub all_votes_commit: pallas::Point, + pub all_vote_commit: pallas::Point, } impl BlindAggregateVote { - //pub fn nullifier_exists(&self, nullifier: &Nullifier) -> bool { - // self.vote_nullifiers.iter().any(|n| n == nullifier) - //} - - pub fn combine(&mut self, other: BlindAggregateVote) { - self.yes_votes_commit += other.yes_votes_commit; - self.all_votes_commit += other.all_votes_commit; + pub fn aggregate(&mut self, other: BlindAggregateVote) { + self.yes_vote_commit += other.yes_vote_commit; + self.all_vote_commit += other.all_vote_commit; } } impl Default for BlindAggregateVote { fn default() -> Self { Self { - yes_votes_commit: pallas::Point::identity(), - all_votes_commit: pallas::Point::identity(), + yes_vote_commit: pallas::Point::identity(), + all_vote_commit: pallas::Point::identity(), } } } @@ -133,8 +129,7 @@ pub struct ExecCallParams { pub proposal: pallas::Base, pub coin_0: pallas::Base, pub coin_1: pallas::Base, - pub yes_votes_commit: pallas::Point, - pub all_votes_commit: pallas::Point, + pub blind_total_vote: BlindAggregateVote, pub input_value_commit: pallas::Point, } diff --git a/src/contract/dao/src/entrypoint.rs b/src/contract/dao/src/entrypoint.rs index edf4bbf10..107524e23 100644 --- a/src/contract/dao/src/entrypoint.rs +++ b/src/contract/dao/src/entrypoint.rs @@ -262,11 +262,11 @@ fn process_instruction(cid: ContractId, ix: &[u8]) -> ContractResult { return Err(ContractError::Custom(7)) } - proposal_votes.all_votes_commit += input.vote_commit; + proposal_votes.all_vote_commit += input.vote_commit; vote_nullifiers.push(input.nullifier); } - proposal_votes.yes_votes_commit += params.yes_vote_commit; + proposal_votes.yes_vote_commit += params.yes_vote_commit; let update = VoteCallUpdate { proposal_bulla: params.proposal_bulla, @@ -324,9 +324,9 @@ fn process_instruction(cid: ContractId, ix: &[u8]) -> ContractResult { }; let proposal_votes: BlindAggregateVote = deserialize(&proposal_votes)?; - // 4. Check yes_votes_commit and all_votes_commit are the same as in BlindAggregateVote - assert!(proposal_votes.yes_votes_commit == params.yes_votes_commit); - assert!(proposal_votes.all_votes_commit == params.all_votes_commit); + // 4. Check yes_vote_commit and all_vote_commit are the same as in BlindAggregateVote + assert!(proposal_votes.yes_vote_commit == params.blind_total_vote.yes_vote_commit); + assert!(proposal_votes.all_vote_commit == params.blind_total_vote.all_vote_commit); let update = ExecCallUpdate { proposal: params.proposal }; let mut update_data = vec![]; @@ -381,8 +381,8 @@ fn process_update(cid: ContractId, ix: &[u8]) -> ContractResult { let update: VoteCallUpdate = deserialize(&ix[1..])?; // Perform this code: - // total_yes_votes_commit += update.yes_vote_commit - // total_all_votes_commit += update.all_vote_commit + // total_yes_vote_commit += update.yes_vote_commit + // total_all_vote_commit += update.all_vote_commit let proposal_vote_db = db_lookup(cid, DAO_PROPOSAL_VOTES_TREE)?; db_set( @@ -499,11 +499,11 @@ fn get_metadata(_: ContractId, ix: &[u8]) -> ContractResult { let mut zk_public_values: Vec<(String, Vec)> = vec![]; let mut signature_pubkeys: Vec = vec![]; - let mut all_votes_commit = pallas::Point::identity(); + let mut all_vote_commit = pallas::Point::identity(); for input in ¶ms.inputs { signature_pubkeys.push(input.signature_public); - all_votes_commit += input.vote_commit; + all_vote_commit += input.vote_commit; let value_coords = input.vote_commit.to_affine().coordinates().unwrap(); let (sig_x, sig_y) = input.signature_public.xy(); @@ -523,7 +523,7 @@ fn get_metadata(_: ContractId, ix: &[u8]) -> ContractResult { } let yes_vote_commit_coords = params.yes_vote_commit.to_affine().coordinates().unwrap(); - let all_vote_commit_coords = all_votes_commit.to_affine().coordinates().unwrap(); + let all_vote_commit_coords = all_vote_commit.to_affine().coordinates().unwrap(); zk_public_values.push(( DAO_CONTRACT_ZKAS_DAO_VOTE_MAIN_NS.to_string(), @@ -552,8 +552,9 @@ fn get_metadata(_: ContractId, ix: &[u8]) -> ContractResult { let mut zk_public_values: Vec<(String, Vec)> = vec![]; let signature_pubkeys: Vec = vec![]; - let yes_votes_coords = params.yes_votes_commit.to_affine().coordinates().unwrap(); - let all_votes_coords = params.all_votes_commit.to_affine().coordinates().unwrap(); + let blind_vote = params.blind_total_vote; + let yes_vote_coords = blind_vote.yes_vote_commit.to_affine().coordinates().unwrap(); + let all_vote_coords = blind_vote.all_vote_commit.to_affine().coordinates().unwrap(); let input_value_coords = params.input_value_commit.to_affine().coordinates().unwrap(); msg!("params.proposal: {:?}", params.proposal); @@ -563,10 +564,10 @@ fn get_metadata(_: ContractId, ix: &[u8]) -> ContractResult { params.proposal, params.coin_0, params.coin_1, - *yes_votes_coords.x(), - *yes_votes_coords.y(), - *all_votes_coords.x(), - *all_votes_coords.y(), + *yes_vote_coords.x(), + *yes_vote_coords.y(), + *all_vote_coords.x(), + *all_vote_coords.y(), *input_value_coords.x(), *input_value_coords.y(), DAO_CONTRACT_ID.inner(), diff --git a/src/contract/dao/tests/integration.rs b/src/contract/dao/tests/integration.rs index 40c5ce70f..837ed805f 100644 --- a/src/contract/dao/tests/integration.rs +++ b/src/contract/dao/tests/integration.rs @@ -28,7 +28,9 @@ use darkfi_serial::{Decodable, Encodable}; use log::debug; use rand::rngs::OsRng; -use darkfi_dao_contract::{dao_client, money_client, note, wallet_cache::WalletCache, DaoFunction}; +use darkfi_dao_contract::{ + dao_client, dao_model, money_client, note, wallet_cache::WalletCache, DaoFunction, +}; use darkfi_money_contract::{client::EncryptedNote, state::MoneyTransferParams, MoneyFunction}; @@ -502,10 +504,8 @@ async fn integration_test() -> Result<()> { let call = dao_client::VoteCall { inputs: vec![input], - vote: dao_client::VoteInfo { - vote_option, - vote_option_blind: pallas::Scalar::random(&mut OsRng), - }, + vote_option, + yes_vote_blind: pallas::Scalar::random(&mut OsRng), vote_keypair: vote_keypair_1, proposal: proposal.clone(), dao: dao.clone(), @@ -541,8 +541,8 @@ async fn integration_test() -> Result<()> { note }; debug!(target: "dao", "User 1 voted!"); - debug!(target: "dao", " vote_option: {}", vote_note_1.vote.vote_option); - debug!(target: "dao", " value: {}", vote_note_1.vote_value); + debug!(target: "dao", " vote_option: {}", vote_note_1.vote_option); + debug!(target: "dao", " value: {}", vote_note_1.all_vote_value); // User 2: NO @@ -572,10 +572,8 @@ async fn integration_test() -> Result<()> { let call = dao_client::VoteCall { inputs: vec![input], - vote: dao_client::VoteInfo { - vote_option, - vote_option_blind: pallas::Scalar::random(&mut OsRng), - }, + vote_option, + yes_vote_blind: pallas::Scalar::random(&mut OsRng), vote_keypair: vote_keypair_2, proposal: proposal.clone(), dao: dao.clone(), @@ -608,8 +606,8 @@ async fn integration_test() -> Result<()> { note }; debug!(target: "dao", "User 2 voted!"); - debug!(target: "dao", " vote_option: {}", vote_note_2.vote.vote_option); - debug!(target: "dao", " value: {}", vote_note_2.vote_value); + debug!(target: "dao", " vote_option: {}", vote_note_2.vote_option); + debug!(target: "dao", " value: {}", vote_note_2.all_vote_value); // User 3: YES @@ -639,10 +637,8 @@ async fn integration_test() -> Result<()> { let call = dao_client::VoteCall { inputs: vec![input], - vote: dao_client::VoteInfo { - vote_option, - vote_option_blind: pallas::Scalar::random(&mut OsRng), - }, + vote_option, + yes_vote_blind: pallas::Scalar::random(&mut OsRng), vote_keypair: vote_keypair_3, proposal: proposal.clone(), dao: dao.clone(), @@ -678,8 +674,8 @@ async fn integration_test() -> Result<()> { note }; debug!(target: "dao", "User 3 voted!"); - debug!(target: "dao", " vote_option: {}", vote_note_3.vote.vote_option); - debug!(target: "dao", " value: {}", vote_note_3.vote_value); + debug!(target: "dao", " vote_option: {}", vote_note_3.vote_option); + debug!(target: "dao", " value: {}", vote_note_3.all_vote_value); // Every votes produces a semi-homomorphic encryption of their vote. // Which is either yes or no @@ -690,52 +686,59 @@ async fn integration_test() -> Result<()> { // voting period. // (that's if we want votes to be hidden during voting) - let mut yes_votes_value = 0; - let mut yes_votes_blind = pallas::Scalar::from(0); - let mut yes_votes_commit = pallas::Point::identity(); + let mut total_yes_vote_value = 0; + let mut total_all_vote_value = 0; - let mut all_votes_value = 0; - let mut all_votes_blind = pallas::Scalar::from(0); - let mut all_votes_commit = pallas::Point::identity(); + let mut blind_total_vote = dao_model::BlindAggregateVote::default(); - // We were previously saving votes to a Vec for testing. - // However since Update is now UpdateBase it gets moved into update.apply(). - // So we need to think of another way to run these tests. - //assert!(updates.len() == 3); + // Just keep track of these for the assert statements after the for loop + // but they aren't needed otherwise. + let mut total_yes_vote_blind = pallas::Scalar::from(0); + let mut total_all_vote_blind = pallas::Scalar::from(0); - for (i, note /* update*/) in [vote_note_1, vote_note_2, vote_note_3] - .iter() /*.zip(updates)*/ - .enumerate() - { - let vote_commit = pedersen_commitment_u64(note.vote_value, note.vote_value_blind); - //assert!(update.value_commit == all_vote_value_commit); - all_votes_commit += vote_commit; - all_votes_blind += note.vote_value_blind; + for (i, note) in [vote_note_1, vote_note_2, vote_note_3].iter().enumerate() { + total_yes_vote_blind += note.yes_vote_blind; + total_all_vote_blind += note.all_vote_blind; - let yes_vote_commit = pedersen_commitment_u64( - note.vote.vote_option as u64 * note.vote_value, - note.vote.vote_option_blind, + // Update private values + + // vote_option is either 0 or 1 + let yes_vote_value = note.vote_option as u64 * note.all_vote_value; + total_yes_vote_value += yes_vote_value; + total_all_vote_value += note.all_vote_value; + + // Update public values + + let yes_vote_commit = pedersen_commitment_u64(yes_vote_value, note.yes_vote_blind); + let all_vote_commit = pedersen_commitment_u64(note.all_vote_value, note.all_vote_blind); + + let blind_vote = dao_model::BlindAggregateVote { yes_vote_commit, all_vote_commit }; + blind_total_vote.aggregate(blind_vote); + + // Just for the debug + let vote_result = match note.vote_option { + true => "yes", + false => "no", + }; + debug!( + target: "dao", + "Voter {} voted {} with {} gDRK", + i, + vote_result, + note.all_vote_value, ); - //assert!(update.yes_vote_commit == yes_vote_commit); - - yes_votes_commit += yes_vote_commit; - yes_votes_blind += note.vote.vote_option_blind; - - let vote_option = note.vote.vote_option; - - if vote_option { - yes_votes_value += note.vote_value; - } - all_votes_value += note.vote_value; - let vote_result: String = if vote_option { "yes".to_string() } else { "no".to_string() }; - - debug!(target: "dao", "Voter {} voted {}", i, vote_result); } - debug!(target: "dao", "Outcome = {} / {}", yes_votes_value, all_votes_value); + debug!(target: "dao", "Outcome = {} / {}", total_yes_vote_value, total_all_vote_value); - assert!(all_votes_commit == pedersen_commitment_u64(all_votes_value, all_votes_blind)); - assert!(yes_votes_commit == pedersen_commitment_u64(yes_votes_value, yes_votes_blind)); + assert!( + blind_total_vote.all_vote_commit == + pedersen_commitment_u64(total_all_vote_value, total_all_vote_blind), + ); + assert!( + blind_total_vote.yes_vote_commit == + pedersen_commitment_u64(total_yes_vote_value, total_yes_vote_blind), + ); // ======================================================= // Execute the vote @@ -820,10 +823,10 @@ async fn integration_test() -> Result<()> { let call = dao_client::ExecCall { proposal, dao, - yes_votes_value, - all_votes_value, - yes_votes_blind, - all_votes_blind, + yes_vote_value: total_yes_vote_value, + all_vote_value: total_all_vote_value, + yes_vote_blind: total_yes_vote_blind, + all_vote_blind: total_all_vote_blind, user_serial, user_coin_blind, dao_serial,