diff --git a/substrate/core/sr-primitives/src/lib.rs b/substrate/core/sr-primitives/src/lib.rs index 22504ba92828871936751b4cc4585ff104d54903..d0eb6efbfd1b30539c402abb00fc573c858c6b47 100644 --- a/substrate/core/sr-primitives/src/lib.rs +++ b/substrate/core/sr-primitives/src/lib.rs @@ -123,14 +123,7 @@ impl BuildStorage for StorageMap { #[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq)] pub struct Permill(u32); -// TODO: impl Mul<Permill> for N where N: As<usize> impl Permill { - /// Multiplication. - pub fn times<N: traits::As<u64> + ::rstd::ops::Mul<N, Output=N> + ::rstd::ops::Div<N, Output=N>>(self, b: N) -> N { - // TODO: handle overflows - b * <N as traits::As<u64>>::sa(self.0 as u64) / <N as traits::As<u64>>::sa(1000000) - } - /// Wraps the argument into `Permill` type. pub fn from_millionths(x: u32) -> Permill { Permill(x) } @@ -142,6 +135,16 @@ impl Permill { pub fn from_fraction(x: f64) -> Permill { Permill((x * 1_000_000.0) as u32) } } +impl<N> ::rstd::ops::Mul<N> for Permill +where + N: traits::As<u64> +{ + type Output = N; + fn mul(self, b: N) -> Self::Output { + <N as traits::As<u64>>::sa(b.as_().saturating_mul(self.0 as u64) / 1_000_000) + } +} + #[cfg(feature = "std")] impl From<f64> for Permill { fn from(x: f64) -> Permill { @@ -178,14 +181,7 @@ impl From<codec::Compact<Permill>> for Permill { #[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq)] pub struct Perbill(u32); -// TODO: impl Mul<Perbill> for N where N: As<usize> impl Perbill { - /// Attenuate `b` by self. - pub fn times<N: traits::As<u64> + ::rstd::ops::Mul<N, Output=N> + ::rstd::ops::Div<N, Output=N>>(self, b: N) -> N { - // TODO: handle overflows - b * <N as traits::As<u64>>::sa(self.0 as u64) / <N as traits::As<u64>>::sa(1_000_000_000) - } - /// Nothing. pub fn zero() -> Perbill { Perbill(0) } @@ -213,6 +209,16 @@ impl Perbill { pub fn from_rational(n: f64, d: f64) -> Perbill { Perbill(((n / d).max(0.0).min(1.0) * 1_000_000_000.0) as u32) } } +impl<N> ::rstd::ops::Mul<N> for Perbill +where + N: traits::As<u64> +{ + type Output = N; + fn mul(self, b: N) -> Self::Output { + <N as traits::As<u64>>::sa(b.as_().saturating_mul(self.0 as u64) / 1_000_000_000) + } +} + #[cfg(feature = "std")] impl From<f64> for Perbill { fn from(x: f64) -> Perbill { @@ -659,4 +665,10 @@ mod tests { let encoded = data.encode(); assert_eq!(data, WithCompact::<super::Perbill>::decode(&mut &encoded[..]).unwrap()); } + + #[test] + fn saturating_mul() { + assert_eq!(super::Perbill::one() * std::u64::MAX, std::u64::MAX/1_000_000_000); + assert_eq!(super::Permill::from_percent(100) * std::u64::MAX, std::u64::MAX/1_000_000); + } } diff --git a/substrate/srml/staking/src/lib.rs b/substrate/srml/staking/src/lib.rs index 879b3b8e499c47a4bd45e8f67689627dbee70fab..f35ae3d436482068b374cdd64d88280becb35366 100644 --- a/substrate/srml/staking/src/lib.rs +++ b/substrate/srml/staking/src/lib.rs @@ -494,8 +494,8 @@ impl<T: Trait> Module<T> { <session::Module<T>>::set_validators(vals); // Update the balances for slashing/rewarding according to the stakes. - <CurrentOfflineSlash<T>>::put(Self::offline_slash().times(stake_range.1)); - <CurrentSessionReward<T>>::put(Self::session_reward().times(stake_range.1)); + <CurrentOfflineSlash<T>>::put(Self::offline_slash() * stake_range.1); + <CurrentSessionReward<T>>::put(Self::session_reward() * stake_range.1); } /// Call when a validator is determined to be offline. `count` is the diff --git a/substrate/srml/treasury/src/lib.rs b/substrate/srml/treasury/src/lib.rs index 7abcebfe922a393dada2c44d54f069d3ca128beb..5437ec5f8273200082ec380a9413a19540a852c3 100644 --- a/substrate/srml/treasury/src/lib.rs +++ b/substrate/srml/treasury/src/lib.rs @@ -201,7 +201,7 @@ impl<T: Trait> Module<T> { /// The needed bond for a proposal whose spend is `value`. fn calculate_bond(value: T::Balance) -> T::Balance { - Self::proposal_bond_minimum().max(Self::proposal_bond().times(value)) + Self::proposal_bond_minimum().max(Self::proposal_bond() * value) } // Spend some money! @@ -238,7 +238,7 @@ impl<T: Trait> Module<T> { if !missed_any { // burn some proportion of the remaining budget if we run a surplus. - let burn = Self::burn().times(budget_remaining).min(budget_remaining); + let burn = (Self::burn() * budget_remaining).min(budget_remaining); budget_remaining -= burn; Self::deposit_event(RawEvent::Burnt(burn)) }