Skip to content

Commit a13cc3e

Browse files
committed
refactor(gamma): big decimal
1 parent 2b4965f commit a13cc3e

File tree

7 files changed

+108
-32
lines changed

7 files changed

+108
-32
lines changed

Cargo.lock

Lines changed: 35 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/audit/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,17 @@ FRAGMENTS_STORAGE=/tmp/fund9-leader-1/persist/leader-1
3131

3232
```
3333

34+
```bash
35+
36+
OFFICIAL_RESULTS=/tmp/activevoteplans.json
37+
BLOCK0=/tmp/fund9-leader-1/artifacts/block0.bin
38+
FRAGMENTS_STORAGE=/tmp/fund9-leader-1/persist/leader-1
39+
QUADRATIC_SCALE=0.1
40+
41+
./target/release/offline --fragments $FRAGMENTS_STORAGE --block0 $BLOCK0 --official-results $OFFICIAL_RESULTS --quadratic_scaling $QUADRATIC_SCALE
42+
43+
```
44+
3445
This will create three files:
3546
- *ledger_after_tally.json* **(decrypted ledger state after tally)** *should match official results!*
3647
- *ledger_before_tally.json* **(encrypted ledger state before tally)**

src/audit/src/offline/bin/main.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use lib::offline::{
1919

2020
use chain_core::packer::Codec;
2121
use color_eyre::{eyre::Context, Report};
22+
use std::env;
2223
use std::{error::Error, path::PathBuf};
2324

2425
///
@@ -36,6 +37,12 @@ pub struct Args {
3637
/// cross reference official results
3738
#[clap(short, long)]
3839
official_results: Option<String>,
40+
/// Quadratic scaling
41+
#[clap(short, long)]
42+
gamma: Option<String>,
43+
/// Quadratic scaling
44+
#[clap(short, long)]
45+
precision: Option<String>,
3946
}
4047

4148
fn main() -> Result<(), Box<dyn Error>> {
@@ -95,6 +102,16 @@ fn main() -> Result<(), Box<dyn Error>> {
95102
// use tally tool to validate decrypted results
96103
let shares_and_results = extract_decryption_shares_and_results(all_fragments);
97104

105+
if let Some(gamma) = args.gamma {
106+
const SCALE_FACTOR: &str = "QUADRATIC_VOTING_SCALING_FACTOR";
107+
std::env::set_var(SCALE_FACTOR, gamma);
108+
}
109+
110+
if let Some(precision) = args.precision {
111+
const PRECISION: &str = "QUADRATIC_VOTING_PRECISION";
112+
std::env::set_var(PRECISION, precision);
113+
}
114+
98115
// Compare decrypted tallies with official results if provided
99116
if let Some(official_results) = args.official_results {
100117
// official catalyst results in json format

src/chain-libs/chain-impl-mockchain/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ criterion = { version = "0.3.0", optional = true }
3232
rand = "0.8"
3333
cryptoxide = "0.4"
3434
tracing.workspace = true
35-
num-integer = "0.1"
35+
bigdecimal = "0.4.7"
3636

3737

3838
[features]

src/chain-libs/chain-impl-mockchain/src/vote/tally.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,14 @@ use crate::{
33
value::Value,
44
vote::{Choice, Options},
55
};
6+
use bigdecimal::BigDecimal;
7+
use bigdecimal::ToPrimitive;
68
use chain_vote::EncryptedTally;
7-
use num_integer::Roots;
9+
use std::num::NonZeroI64;
10+
11+
use std::str::FromStr;
12+
13+
use std::env;
814
use std::fmt;
915
use thiserror::Error;
1016

@@ -167,11 +173,22 @@ impl TallyResult {
167173
} else {
168174
let index = choice.as_byte() as usize;
169175

170-
// Returns the truncated principal square root of an integer – ⌊√x⌋
171-
// This is solving for r in r² = x, rounding toward zero. The result will satisfy r² ≤ x < (r+1)²
172-
let weight_gammad = weight.0.sqrt();
176+
const SCALE_FACTOR: &str = "QUADRATIC_VOTING_SCALING_FACTOR";
177+
const PRECISION: &str = "QUADRATIC_VOTING_PRECISION";
178+
179+
let scaling_factor = env::var(SCALE_FACTOR).unwrap_or(1.to_string());
180+
let precision =
181+
i64::from_str(&env::var(PRECISION).unwrap_or(1.to_string())).unwrap_or(1);
182+
183+
let gamma = BigDecimal::from_str(&scaling_factor).unwrap_or(BigDecimal::from(1));
184+
let stake = BigDecimal::from(weight.0);
185+
186+
let weight = (gamma * stake)
187+
.round(precision)
188+
.to_u64()
189+
.unwrap_or(weight.0);
173190

174-
self.results[index] = self.results[index].saturating_add(Weight(weight_gammad));
191+
self.results[index] = self.results[index].saturating_add(Weight(weight));
175192

176193
Ok(())
177194
}

src/chain-libs/chain-vote/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ cryptoxide = "^0.4.2"
1515
const_format = "0.2"
1616
base64 = "0.21.0"
1717
tracing = "0.1"
18-
num-integer = "0.1"
18+
bigdecimal = "0.4.7"
19+
1920

2021

2122
[dev-dependencies]

src/chain-libs/chain-vote/src/tally.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
use std::num::NonZeroI64;
12
use std::num::NonZeroU64;
23

4+
use std::str::FromStr;
5+
36
use crate::GroupElement;
47
use crate::{
58
committee::*,
@@ -9,9 +12,13 @@ use crate::{
912
TallyOptimizationTable,
1013
};
1114
use base64::{engine::general_purpose, Engine as _};
15+
16+
use bigdecimal::BigDecimal;
17+
use bigdecimal::ToPrimitive;
1218
use cryptoxide::blake2b::Blake2b;
1319
use cryptoxide::digest::Digest;
14-
use num_integer::Roots;
20+
21+
use std::env;
1522

1623
use rand_core::{CryptoRng, RngCore};
1724

@@ -158,14 +165,21 @@ impl EncryptedTally {
158165
assert_eq!(ballot.vote().len(), self.r.len());
159166
assert_eq!(ballot.fingerprint(), &self.fingerprint);
160167

161-
// Returns the truncated principal square root of an integer – ⌊√x⌋
162-
// This is solving for r in r² = x, rounding toward zero. The result will satisfy r² ≤ x < (r+1)²
163-
let weight_gammad = weight.sqrt();
168+
const SCALE_FACTOR: &str = "QUADRATIC_VOTING_SCALING_FACTOR";
169+
const PRECISION: &str = "QUADRATIC_VOTING_PRECISION";
170+
171+
let scaling_factor = env::var(SCALE_FACTOR).unwrap_or(1.to_string());
172+
let precision = i64::from_str(&env::var(PRECISION).unwrap_or(1.to_string())).unwrap_or(1);
173+
174+
let gamma = BigDecimal::from_str(&scaling_factor).unwrap_or(BigDecimal::from(1));
175+
let stake = BigDecimal::from(weight);
176+
177+
let weight = (gamma * stake).round(precision).to_u64().unwrap_or(weight);
164178

165179
for (ri, ci) in self.r.iter_mut().zip(ballot.vote().iter()) {
166-
*ri = &*ri + &(ci * weight_gammad);
180+
*ri = &*ri + &(ci * weight);
167181
}
168-
self.max_stake += weight_gammad;
182+
self.max_stake += weight;
169183
}
170184

171185
/// Given a single committee member's `secret_key`, returns a partial decryption of

0 commit comments

Comments
 (0)