Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion bin/node/runtime/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ mod multiplier_tests {
let m = max_normal() as f64;
// block weight always truncated to max weight
let block_weight = (block_weight as f64).min(m);
let v: f64 = AdjustmentVariable::get().to_fraction();
let v: f64 = AdjustmentVariable::get().to_float();

// Ideal saturation in terms of weight
let ss = target() as f64;
Expand Down
6 changes: 3 additions & 3 deletions frame/contracts/proc-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,17 +117,17 @@ fn format_weight(field: &Ident) -> TokenStream {
&if self.#field > 1_000_000_000 {
format!(
"{:.1?} ms",
Fixed::saturating_from_rational(self.#field, 1_000_000_000).to_fraction()
Fixed::saturating_from_rational(self.#field, 1_000_000_000).to_float()
)
} else if self.#field > 1_000_000 {
format!(
"{:.1?} µs",
Fixed::saturating_from_rational(self.#field, 1_000_000).to_fraction()
Fixed::saturating_from_rational(self.#field, 1_000_000).to_float()
)
} else if self.#field > 1_000 {
format!(
"{:.1?} ns",
Fixed::saturating_from_rational(self.#field, 1_000).to_fraction()
Fixed::saturating_from_rational(self.#field, 1_000).to_float()
)
} else {
format!("{} ps", self.#field)
Expand Down
1 change: 1 addition & 0 deletions primitives/arithmetic/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ targets = ["x86_64-unknown-linux-gnu"]
[dependencies]
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] }
integer-sqrt = "0.1.2"
static_assertions = "1.1.0"
num-traits = { version = "0.2.8", default-features = false }
sp-std = { version = "3.0.0", default-features = false, path = "../std" }
serde = { version = "1.0.101", optional = true, features = ["derive"] }
Expand Down
50 changes: 23 additions & 27 deletions primitives/arithmetic/src/biguint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ const SHIFT: usize = 32;
/// short form of _Base_. Analogous to the value 10 in base-10 decimal numbers.
const B: Double = Single::max_value() as Double + 1;

static_assertions::const_assert!(
sp_std::mem::size_of::<Double>() - sp_std::mem::size_of::<Single>() == SHIFT / 8
);

/// Splits a [`Double`] limb number into a tuple of two [`Single`] limb numbers.
pub fn split(a: Double) -> (Single, Single) {
let al = a as Single;
Expand Down Expand Up @@ -187,6 +191,7 @@ impl BigUint {
let u = Double::from(self.checked_get(j).unwrap_or(0));
let v = Double::from(other.checked_get(j).unwrap_or(0));
let s = u + v + k;
// proof: any number % B will fit into `Single`.
w.set(j, (s % B) as Single);
k = s / B;
}
Expand All @@ -209,28 +214,24 @@ impl BigUint {
let s = {
let u = Double::from(self.checked_get(j).unwrap_or(0));
let v = Double::from(other.checked_get(j).unwrap_or(0));
let mut needs_borrow = false;
let mut t = 0;

if let Some(v1) = u.checked_sub(v) {
if let Some(v2) = v1.checked_sub(k) {
t = v2;
k = 0;
} else {
needs_borrow = true;
}
if let Some(v2) = u.checked_sub(v).and_then(|v1| v1.checked_sub(k)) {
// no borrow is needed. u - v - k can be computed as-is
let t = v2;
k = 0;

t
} else {
needs_borrow = true;
}
if needs_borrow {
t = u + B - v - k;
// borrow is needed. Add a `B` to u, before subtracting.
// PROOF: addition: `u + B < 2*B`, thus can fit in double.
// PROOF: subtraction: if `u - v - k < 0`, then `u + B - v - k < B`.
// NOTE: the order of operations is critical to ensure underflow won't happen.
let t = u + B - v - k;
k = 1;

t
}
t
};
// PROOF: t either comes from `v2`, or from `u + B - v - k`. The former is
// trivial. The latter will not overflow this branch will only happen if the sum of
// `u - v - k` part has been negative, hence `u + B - v - k < B`.
w.set(j, s as Single);
}

Expand Down Expand Up @@ -264,10 +265,9 @@ impl BigUint {
let mut k = 0;
for i in 0..m {
// PROOF: (B−1) × (B−1) + (B−1) + (B−1) = B^2 −1 < B^2. addition is safe.
let t =
mul_single(self.get(j), other.get(i))
+ Double::from(w.get(i + j))
+ Double::from(k);
let t = mul_single(self.get(j), other.get(i))
+ Double::from(w.get(i + j))
+ Double::from(k);
w.set(i + j, (t % B) as Single);
// PROOF: (B^2 - 1) / B < B. conversion is safe.
k = (t / B) as Single;
Expand Down Expand Up @@ -580,12 +580,6 @@ pub mod tests {
BigUint { digits: vec![1; n] }
}

#[test]
fn shift_check() {
let shift = sp_std::mem::size_of::<Double>() - sp_std::mem::size_of::<Single>();
assert_eq!(shift * 8, SHIFT);
}

#[test]
fn split_works() {
let a = SHIFT / 2;
Expand Down Expand Up @@ -732,12 +726,14 @@ pub mod tests {
let c = BigUint { digits: vec![1, 1, 2] };
let d = BigUint { digits: vec![0, 2] };
let e = BigUint { digits: vec![0, 1, 1, 2] };
let f = BigUint { digits: vec![7, 8] };

assert!(a.clone().div(&b, true).is_none());
assert!(c.clone().div(&a, true).is_none());
assert!(c.clone().div(&d, true).is_none());
assert!(e.clone().div(&a, true).is_none());

assert!(f.clone().div(&b, true).is_none());
assert!(c.clone().div(&b, true).is_some());
}

Expand Down
2 changes: 1 addition & 1 deletion primitives/arithmetic/src/fixed_point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ macro_rules! implement_fixed {
}

#[cfg(any(feature = "std", test))]
pub fn to_fraction(self) -> f64 {
pub fn to_float(self) -> f64 {
self.0 as f64 / <Self as FixedPointNumber>::DIV as f64
}
}
Expand Down