Skip to content

Commit d3c221a

Browse files
committed
refactor(big rational): fraction to denom and numer
1 parent 59fbc52 commit d3c221a

File tree

5 files changed

+46
-32
lines changed

5 files changed

+46
-32
lines changed

Cargo.lock

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

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ rand = "0.8"
3333
cryptoxide = "0.4"
3434
tracing.workspace = true
3535
bigdecimal = "0.4.7"
36+
num = "0.4.3"
3637

3738

3839
[features]

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

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use crate::{
66
use bigdecimal::BigDecimal;
77
use bigdecimal::ToPrimitive;
88
use chain_vote::EncryptedTally;
9+
use num::BigRational;
10+
use num::{BigInt, FromPrimitive};
911
use std::num::NonZeroI64;
1012

1113
use std::str::FromStr;
@@ -177,19 +179,19 @@ impl TallyResult {
177179
const PRECISION: &str = "QUADRATIC_VOTING_PRECISION";
178180

179181
// Apply quadratic scaling if gamma value specified in env var. Else gamma is 1 and has no effect.
180-
let gamma = env::var(GAMMA).unwrap_or(1.to_string());
182+
let gamma = f64::from_str(&env::var(GAMMA).unwrap_or(1.0.to_string())).unwrap();
181183

182184
let precision =
183185
i64::from_str(&env::var(PRECISION).unwrap_or(1.to_string())).unwrap_or(1);
184186

185-
let mut gamma = BigDecimal::from_str(&gamma).unwrap_or(BigDecimal::from(1));
186-
// Gamma must be between 0 and 1, anything else is treated as bad input; defaulting gamma to 1.
187-
if gamma < BigDecimal::from(0) || gamma > BigDecimal::from(1) {
188-
gamma = BigDecimal::from(1);
189-
}
187+
let gamma =
188+
BigRational::from_f64(gamma).unwrap_or(BigRational::from_integer(BigInt::from(1)));
189+
let denom = BigDecimal::from_bigint(gamma.denom().clone(), precision);
190+
let numer = BigDecimal::from_bigint(gamma.numer().clone(), precision);
191+
190192
let stake = BigDecimal::from(weight.0);
191193

192-
let weight = (gamma * stake)
194+
let weight = ((stake.clone() * numer.clone()) / denom)
193195
.round(precision)
194196
.to_u64()
195197
.unwrap_or(weight.0);

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ cryptoxide = "^0.4.2"
1515
const_format = "0.2"
1616
base64 = "0.21.0"
1717
bigdecimal = "0.4.7"
18+
num = "0.4.3"
19+
tracing = "*"
1820

1921

2022
[dev-dependencies]

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

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ use crate::{
1212
TallyOptimizationTable,
1313
};
1414
use base64::{engine::general_purpose, Engine as _};
15+
use num::BigInt;
16+
use num::BigRational;
17+
use num::FromPrimitive;
18+
use tracing::info;
1519

1620
use bigdecimal::BigDecimal;
1721
use bigdecimal::ToPrimitive;
@@ -169,17 +173,22 @@ impl EncryptedTally {
169173
const PRECISION: &str = "QUADRATIC_VOTING_PRECISION";
170174

171175
// Apply quadratic scaling if gamma value specified in env var. Else gamma is 1 and has no effect.
172-
let gamma = env::var(GAMMA).unwrap_or(1.to_string());
176+
let gamma = f64::from_str(&env::var(GAMMA).unwrap_or(1.0.to_string())).unwrap();
173177
let precision = i64::from_str(&env::var(PRECISION).unwrap_or(1.to_string())).unwrap_or(1);
174178

175-
let mut gamma = BigDecimal::from_str(&gamma).unwrap_or(BigDecimal::from(1));
176-
// Gamma must be between 0 and 1, anything else is treated as bad input; defaulting gamma to 1.
177-
if gamma < BigDecimal::from(0) || gamma > BigDecimal::from(1) {
178-
gamma = BigDecimal::from(1);
179-
}
179+
let gamma =
180+
BigRational::from_f64(gamma).unwrap_or(BigRational::from_integer(BigInt::from(1)));
181+
let denom = BigDecimal::from_bigint(gamma.denom().clone(), precision);
182+
let numer = BigDecimal::from_bigint(gamma.numer().clone(), precision);
183+
180184
let stake = BigDecimal::from(weight);
181185

182-
let weight = (gamma * stake).round(precision).to_u64().unwrap_or(weight);
186+
let weight = ((stake.clone() * numer.clone()) / denom)
187+
.round(precision)
188+
.to_u64()
189+
.unwrap_or(weight);
190+
191+
info!("stake before {:?} stake after {:?}", stake.to_u64(), weight);
183192

184193
for (ri, ci) in self.r.iter_mut().zip(ballot.vote().iter()) {
185194
*ri = &*ri + &(ci * weight);

0 commit comments

Comments
 (0)