dao: improve confusing vote/ value names.

TLDR: win_votes is now weighted_votes. total_votes is now all_votes.

decided on weighted_votes instead of yes_votes because otherwise the fact
that we create it by commiting to yes_vote_value and all_vote_blinds is
confusing.

i.e:

    weighted_vote_commits = commit(yes_vote_values, all_vote_blinds)

is easier to understand than:

    yes_vote_commits = commit(yes_vote_values, all_vote_blinds)
This commit is contained in:
lunar-mining
2022-09-04 13:28:35 +02:00
parent 1643902e8b
commit d9451f7eef
7 changed files with 102 additions and 96 deletions

View File

@@ -22,10 +22,10 @@ contract "DaoExec" {
Base dao_bulla_blind,
# votes
Base win_votes,
Base total_votes,
Scalar win_votes_blind,
Scalar total_votes_blind,
Base yes_vote_values,
Base all_vote_values,
Scalar all_vote_blinds,
Scalar all_vote_value_blinds,
# outputs + inputs
Base user_serial,
@@ -98,26 +98,25 @@ circuit "DaoExec" {
# Create pedersen commits for win_votes, and total_votes
# and make public
win_votes_v = ec_mul_short(win_votes, VALUE_COMMIT_VALUE);
win_votes_r = ec_mul(win_votes_blind, VALUE_COMMIT_RANDOM);
win_votes_commit = ec_add(win_votes_v, win_votes_r);
yes_vote_values_c = ec_mul_short(yes_vote_values, VALUE_COMMIT_VALUE);
all_vote_blinds_c = ec_mul(all_vote_blinds, VALUE_COMMIT_RANDOM);
weighted_votes_commit = ec_add(yes_vote_values_c, all_vote_blinds_c);
# get curve points and constrain
win_votes_commit_x = ec_get_x(win_votes_commit);
win_votes_commit_y = ec_get_y(win_votes_commit);
constrain_instance(win_votes_commit_x);
constrain_instance(win_votes_commit_y);
weighted_votes_commit_x = ec_get_x(weighted_votes_commit);
weighted_votes_commit_y = ec_get_y(weighted_votes_commit);
constrain_instance(weighted_votes_commit_x);
constrain_instance(weighted_votes_commit_y);
total_votes_v = ec_mul_short(total_votes, VALUE_COMMIT_VALUE);
total_votes_r = ec_mul(total_votes_blind, VALUE_COMMIT_RANDOM);
total_votes_commit = ec_add(total_votes_v, total_votes_r);
all_vote_values_c = ec_mul_short(all_vote_values, VALUE_COMMIT_VALUE);
all_vote_value_blinds_c = ec_mul(all_vote_value_blinds, VALUE_COMMIT_RANDOM);
all_vote_values_commit = ec_add(all_vote_values_c, all_vote_value_blinds_c);
# get curve points and constrain
total_votes_commit_x = ec_get_x(total_votes_commit);
total_votes_commit_y = ec_get_y(total_votes_commit);
constrain_instance(total_votes_commit_x);
constrain_instance(total_votes_commit_y);
all_vote_values_commit_x = ec_get_x(all_vote_values_commit);
all_vote_values_commit_y = ec_get_y(all_vote_values_commit);
constrain_instance(all_vote_values_commit_x);
constrain_instance(all_vote_values_commit_y);
# Create pedersen commit for input_value and make public

View File

@@ -59,18 +59,20 @@ pub struct CallData {
pub proposal: pallas::Base,
pub coin_0: pallas::Base,
pub coin_1: pallas::Base,
pub win_votes_commit: pallas::Point,
pub total_votes_commit: pallas::Point,
pub weighted_votes_commit: pallas::Point,
pub all_vote_values_commit: pallas::Point,
pub input_value_commit: pallas::Point,
}
impl CallDataBase for CallData {
fn zk_public_values(&self) -> Vec<(String, Vec<DrkCircuitField>)> {
let win_votes_coords = self.win_votes_commit.to_affine().coordinates().unwrap();
let weighted_votes_commit_coords =
self.weighted_votes_commit.to_affine().coordinates().unwrap();
let total_votes_coords = self.total_votes_commit.to_affine().coordinates().unwrap();
let all_vote_values_commit_coords =
self.all_vote_values_commit.to_affine().coordinates().unwrap();
let input_value_coords = self.input_value_commit.to_affine().coordinates().unwrap();
let input_value_commit_coords = self.input_value_commit.to_affine().coordinates().unwrap();
vec![(
"dao-exec".to_string(),
@@ -78,12 +80,12 @@ impl CallDataBase for CallData {
self.proposal,
self.coin_0,
self.coin_1,
*win_votes_coords.x(),
*win_votes_coords.y(),
*total_votes_coords.x(),
*total_votes_coords.y(),
*input_value_coords.x(),
*input_value_coords.y(),
*weighted_votes_commit_coords.x(),
*weighted_votes_commit_coords.y(),
*all_vote_values_commit_coords.x(),
*all_vote_values_commit_coords.y(),
*input_value_commit_coords.x(),
*input_value_commit_coords.y(),
*super::FUNC_ID,
pallas::Base::from(0),
pallas::Base::from(0),
@@ -176,11 +178,11 @@ pub fn state_transition(
let proposal_votes = state.proposal_votes.get(&HashableBase(call_data.proposal)).unwrap();
// 4. check win/total_vote_commit is the same as in ProposalVote
if proposal_votes.vote_commits != call_data.win_votes_commit {
if proposal_votes.weighted_vote_commits != call_data.weighted_votes_commit {
return Err(Error::InvalidVoteCommit)
}
// 5. also check total_vote_commit
if proposal_votes.value_commits != call_data.total_votes_commit {
if proposal_votes.all_vote_value_commits != call_data.all_vote_values_commit {
return Err(Error::InvalidVoteCommit)
}

View File

@@ -23,10 +23,10 @@ use crate::{
pub struct Builder {
pub proposal: Proposal,
pub dao: DaoParams,
pub win_votes: u64,
pub total_votes: u64,
pub win_votes_blind: pallas::Scalar,
pub total_votes_blind: pallas::Scalar,
pub yes_vote_values: u64,
pub all_vote_values: u64,
pub all_vote_blinds: pallas::Scalar,
pub all_vote_value_blinds: pallas::Scalar,
pub user_serial: pallas::Base,
pub user_coin_blind: pallas::Base,
pub dao_serial: pallas::Base,
@@ -104,14 +104,17 @@ impl Builder {
self.dao_coin_blind,
]);
let win_votes_commit = pedersen_commitment_u64(self.win_votes, self.win_votes_blind);
let win_votes_coords = win_votes_commit.to_affine().coordinates().unwrap();
let weighted_votes_commit =
pedersen_commitment_u64(self.yes_vote_values, self.all_vote_blinds);
let weighted_votes_commit_coords = weighted_votes_commit.to_affine().coordinates().unwrap();
let total_votes_commit = pedersen_commitment_u64(self.total_votes, self.total_votes_blind);
let total_votes_coords = total_votes_commit.to_affine().coordinates().unwrap();
let all_vote_values_commit =
pedersen_commitment_u64(self.all_vote_values, self.all_vote_value_blinds);
let all_vote_values_commit_coords =
all_vote_values_commit.to_affine().coordinates().unwrap();
let input_value_commit = pedersen_commitment_u64(self.input_value, self.input_value_blind);
let input_value_coords = input_value_commit.to_affine().coordinates().unwrap();
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 {
@@ -139,10 +142,10 @@ impl Builder {
Witness::Base(Value::known(*dao_pubkey_coords.y())),
Witness::Base(Value::known(self.dao.bulla_blind)),
// votes
Witness::Base(Value::known(pallas::Base::from(self.win_votes))),
Witness::Base(Value::known(pallas::Base::from(self.total_votes))),
Witness::Scalar(Value::known(self.win_votes_blind)),
Witness::Scalar(Value::known(self.total_votes_blind)),
Witness::Base(Value::known(pallas::Base::from(self.yes_vote_values))),
Witness::Base(Value::known(pallas::Base::from(self.all_vote_values))),
Witness::Scalar(Value::known(self.all_vote_blinds)),
Witness::Scalar(Value::known(self.all_vote_value_blinds)),
// outputs + inputs
Witness::Base(Value::known(self.user_serial)),
Witness::Base(Value::known(self.user_coin_blind)),
@@ -160,12 +163,12 @@ impl Builder {
proposal_bulla,
coin_0,
coin_1,
*win_votes_coords.x(),
*win_votes_coords.y(),
*total_votes_coords.x(),
*total_votes_coords.y(),
*input_value_coords.x(),
*input_value_coords.y(),
*weighted_votes_commit_coords.x(),
*weighted_votes_commit_coords.y(),
*all_vote_values_commit_coords.x(),
*all_vote_values_commit_coords.y(),
*input_value_commit_coords.x(),
*input_value_commit_coords.y(),
self.hook_dao_exec,
user_spend_hook,
user_data,
@@ -182,8 +185,8 @@ impl Builder {
proposal: proposal_bulla,
coin_0,
coin_1,
win_votes_commit,
total_votes_commit,
weighted_votes_commit,
all_vote_values_commit,
input_value_commit,
};

View File

@@ -16,9 +16,9 @@ type MerkleTree = BridgeTree<MerkleNode, MERKLE_DEPTH>;
pub struct ProposalVotes {
// TODO: might be more logical to have 'yes_vote_commits' and 'no_vote_commits'
/// Weighted vote commits
pub vote_commits: pallas::Point,
pub weighted_vote_commits: pallas::Point,
/// All value staked in the vote
pub value_commits: pallas::Point,
pub all_vote_value_commits: pallas::Point,
/// Vote nullifiers
pub vote_nulls: Vec<Nullifier>,
}
@@ -69,8 +69,8 @@ impl State {
self.proposal_votes.insert(
HashableBase(bulla),
ProposalVotes {
vote_commits: pallas::Point::identity(),
value_commits: pallas::Point::identity(),
weighted_vote_commits: pallas::Point::identity(),
all_vote_value_commits: pallas::Point::identity(),
vote_nulls: Vec::new(),
},
);

View File

@@ -79,7 +79,8 @@ impl CallDataBase for CallData {
));
}
let vote_commit_coords = self.header.vote_commit.to_affine().coordinates().unwrap();
let weighted_vote_commit_coords =
self.header.weighted_vote_commit.to_affine().coordinates().unwrap();
let value_commit_coords = total_value_commit.to_affine().coordinates().unwrap();
@@ -88,8 +89,8 @@ impl CallDataBase for CallData {
vec![
self.header.token_commit,
self.header.proposal_bulla,
*vote_commit_coords.x(),
*vote_commit_coords.y(),
*weighted_vote_commit_coords.x(),
*weighted_vote_commit_coords.y(),
*value_commit_coords.x(),
*value_commit_coords.y(),
],
@@ -122,7 +123,7 @@ impl CallDataBase for CallData {
pub struct Header {
pub token_commit: pallas::Base,
pub proposal_bulla: pallas::Base,
pub vote_commit: pallas::Point,
pub weighted_vote_commit: pallas::Point,
pub enc_note: EncryptedNote2,
}
@@ -182,7 +183,7 @@ pub fn state_transition(
Ok(Box::new(Update {
proposal_bulla: call_data.header.proposal_bulla,
vote_nulls,
vote_commit: call_data.header.vote_commit,
weighted_vote_commit: call_data.header.weighted_vote_commit,
value_commit: total_value_commit,
}))
}
@@ -191,7 +192,7 @@ pub fn state_transition(
pub struct Update {
proposal_bulla: pallas::Base,
vote_nulls: Vec<Nullifier>,
pub vote_commit: pallas::Point,
pub weighted_vote_commit: pallas::Point,
pub value_commit: pallas::Point,
}
@@ -199,8 +200,8 @@ impl UpdateBase for Update {
fn apply(mut self: Box<Self>, states: &mut StateRegistry) {
let state = states.lookup_mut::<DaoState>(*dao_contract::CONTRACT_ID).unwrap();
let votes_info = state.lookup_proposal_votes_mut(self.proposal_bulla).unwrap();
votes_info.vote_commits += self.vote_commit;
votes_info.value_commits += self.value_commit;
votes_info.weighted_vote_commits += self.weighted_vote_commit;
votes_info.all_vote_value_commits += self.value_commit;
votes_info.vote_nulls.append(&mut self.vote_nulls);
}
}

View File

@@ -221,9 +221,10 @@ impl Builder {
let weighted_vote = vote * value;
let vote_commit = pedersen_commitment_u64(weighted_vote, self.vote.vote_option_blind);
debug!(target: "demo::dao_contract::vote::wallet::Builder", "vote commit: {:?}", vote_commit);
let vote_coords = vote_commit.to_affine().coordinates().unwrap();
let weighted_vote_commit =
pedersen_commitment_u64(weighted_vote, self.vote.vote_option_blind);
debug!(target: "demo::dao_contract::vote::wallet::Builder", "weighted vote commit: {:?}", weighted_vote_commit);
let vote_coords = weighted_vote_commit.to_affine().coordinates().unwrap();
let vote = pallas::Base::from(vote);
let value_commit = pedersen_commitment_u64(value, value_blind);
@@ -284,7 +285,7 @@ impl Builder {
let note = Note { vote: self.vote, value, value_blind };
let enc_note = note::encrypt(&note, &self.vote_keypair.public).unwrap();
let header = Header { token_commit, proposal_bulla, vote_commit, enc_note };
let header = Header { token_commit, proposal_bulla, weighted_vote_commit, enc_note };
let call_data = CallData { header, inputs };

View File

@@ -1130,12 +1130,12 @@ pub async fn demo() -> Result<()> {
// voting period.
// (that's if we want votes to be hidden during voting)
let mut win_votes = 0;
let mut total_votes = 0;
let mut total_vote_blinds = pallas::Scalar::from(0);
let mut total_value_blinds = pallas::Scalar::from(0);
let mut total_value_commit = pallas::Point::identity();
let mut total_vote_commit = pallas::Point::identity();
let mut yes_vote_values = 0;
let mut all_vote_values = 0;
let mut all_vote_blinds = pallas::Scalar::from(0);
let mut all_vote_value_blinds = pallas::Scalar::from(0);
let mut all_vote_value_commits = pallas::Point::identity();
let mut weighted_vote_commits = pallas::Point::identity();
// We were previously saving votes to a Vec<Update> for testing.
// However since Update is now UpdateBase it gets moved into update.apply().
@@ -1146,39 +1146,37 @@ pub async fn demo() -> Result<()> {
.iter() /*.zip(updates)*/
.enumerate()
{
let value_commit = pedersen_commitment_u64(note.value, note.value_blind);
//let update = update.as_any().downcast_ref::<dao_contract::vote::validate::Update>();
//let update = update.unwrap();
//assert!(update.value_commit == value_commit);
let all_vote_value_commit = pedersen_commitment_u64(note.value, note.value_blind);
//assert!(update.value_commit == all_vote_value_commit);
all_vote_value_commits += all_vote_value_commit;
all_vote_value_blinds += note.value_blind;
total_value_commit += value_commit;
total_value_blinds += note.value_blind;
let vote_commit = pedersen_commitment_u64(
let weighted_vote_commit = pedersen_commitment_u64(
note.vote.vote_option as u64 * note.value,
note.vote.vote_option_blind,
);
//assert!(update.weighted_vote_commit == weighted_vote_commit);
//assert!(update.vote_commit == vote_commit);
total_vote_commit += vote_commit;
total_vote_blinds += note.vote.vote_option_blind;
weighted_vote_commits += weighted_vote_commit;
all_vote_blinds += note.vote.vote_option_blind;
let vote_option = note.vote.vote_option;
if vote_option {
win_votes += note.value;
yes_vote_values += note.value;
}
total_votes += note.value;
all_vote_values += note.value;
let vote_result: String = if vote_option { "yes".to_string() } else { "no".to_string() };
debug!("Voter {} voted {}", i, vote_result);
}
debug!("Outcome = {} / {}", win_votes, total_votes);
debug!("Outcome = {} / {}", yes_vote_values, all_vote_values);
assert!(total_value_commit == pedersen_commitment_u64(total_votes, total_value_blinds));
assert!(total_vote_commit == pedersen_commitment_u64(win_votes, total_vote_blinds));
assert!(
all_vote_value_commits == pedersen_commitment_u64(all_vote_values, all_vote_value_blinds)
);
assert!(weighted_vote_commits == pedersen_commitment_u64(yes_vote_values, all_vote_blinds));
///////////////////////////////////////////////////
// Execute the vote
@@ -1249,10 +1247,12 @@ pub async fn demo() -> Result<()> {
let builder = dao_contract::exec::wallet::Builder {
proposal,
dao: dao_params,
win_votes,
total_votes,
win_votes_blind: total_vote_blinds,
total_votes_blind: total_value_blinds,
yes_vote_values,
all_vote_values,
//win_votes_blind: total_vote_blinds,
all_vote_blinds,
//total_votes_blind: total_value_blinds,
all_vote_value_blinds,
user_serial,
user_coin_blind,
dao_serial,