Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
babe: remove error fallback from threshold calculation (#5764)
Browse files Browse the repository at this point in the history
* babe: remove error fallbacks from threshold calculation

* babe: fix indent

* babe: fix domain

* babe: fix compilation

* babe: improve expect

* babe: add one more note about p's limit
  • Loading branch information
andresilva authored Apr 24, 2020
1 parent 7809261 commit 688f702
Showing 1 changed file with 38 additions and 8 deletions.
46 changes: 38 additions & 8 deletions client/consensus/babe/src/authorship.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,44 @@ pub(super) fn calculate_primary_threshold(
authorities[authority_index].1 as f64 /
authorities.iter().map(|(_, weight)| weight).sum::<u64>() as f64;

let calc = || {
let p = BigRational::from_float(1f64 - (1f64 - c).powf(theta))?;
let numer = p.numer().to_biguint()?;
let denom = p.denom().to_biguint()?;
((BigUint::one() << 128) * numer / denom).to_u128()
};

calc().unwrap_or(u128::max_value())
assert!(theta > 0.0, "authority with weight 0.");

// NOTE: in the equation `p = 1 - (1 - c)^theta` the value of `p` is always
// capped by `c`. For all pratical purposes `c` should always be set to a
// value < 0.5, as such in the computations below we should never be near
// edge cases like `0.999999`.

let p = BigRational::from_float(1f64 - (1f64 - c).powf(theta)).expect(
"returns None when the given value is not finite; \
c is a configuration parameter defined in (0, 1]; \
theta must be > 0 if the given authority's weight is > 0; \
theta represents the validator's relative weight defined in (0, 1]; \
powf will always return values in (0, 1] given both the \
base and exponent are in that domain; \
qed.",
);

let numer = p.numer().to_biguint().expect(
"returns None when the given value is negative; \
p is defined as `1 - n` where n is defined in (0, 1]; \
p must be a value in [0, 1); \
qed."
);

let denom = p.denom().to_biguint().expect(
"returns None when the given value is negative; \
p is defined as `1 - n` where n is defined in (0, 1]; \
p must be a value in [0, 1); \
qed."
);

((BigUint::one() << 128) * numer / denom).to_u128().expect(
"returns None if the underlying value cannot be represented with 128 bits; \
we start with 2^128 which is one more than can be represented with 128 bits; \
we multiple by p which is defined in [0, 1); \
the result must be lower than 2^128 by at least one and thus representable with 128 bits; \
qed.",
)
}

/// Returns true if the given VRF output is lower than the given threshold,
Expand Down

0 comments on commit 688f702

Please sign in to comment.