Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 38 additions & 8 deletions client/consensus/babe/src/authorship.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,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