Merge rust-bitcoin/rust-bitcoin#1643: pow: Remove Mul/Div by arbitrary integer types
dd316e4d14
pow: Remove Mul/Div by arbitrary integer types (Tobin C. Harding) Pull request description: When we added `Target` and `Work` types we implemented multiplication and division by anything `Into<u64>`, this is not typically done in the Rust stdlib and also is semantically incorrect for the types. Remove `Mul` and `Div` impls from `Target` and `Work`. Also remove `Mul<T>` for `T: Into<u64>` from the private `U256` type. Fix #1632 ACKs for top commit: apoelstra: ACKdd316e4d14
Kixunil: ACKdd316e4d14
Tree-SHA512: ede53555844adab321ff344535b7b8bab3c5c73855823dfc3ad728b077ae199451b7e22a1d203ef73a076073b7f0cbf9637cefa5fe82fc78ab454d02fa0b62b9
This commit is contained in:
commit
fefaedc755
|
@ -21,20 +21,6 @@ use crate::io::{self, Read, Write};
|
||||||
use crate::prelude::String;
|
use crate::prelude::String;
|
||||||
use crate::string::FromHexStr;
|
use crate::string::FromHexStr;
|
||||||
|
|
||||||
/// Implements $int * $ty. Requires `u64::from($int)`.
|
|
||||||
macro_rules! impl_int_mul {
|
|
||||||
($ty:ident, $($int:ident),+ $(,)?) => {
|
|
||||||
$(
|
|
||||||
impl Mul<$ty> for $int {
|
|
||||||
|
|
||||||
type Output = $ty;
|
|
||||||
#[inline]
|
|
||||||
fn mul(self, rhs: $ty) -> $ty { $ty(self.mul(rhs.0)) }
|
|
||||||
}
|
|
||||||
)+
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implement traits and methods shared by `Target` and `Work`.
|
/// Implement traits and methods shared by `Target` and `Work`.
|
||||||
macro_rules! do_impl {
|
macro_rules! do_impl {
|
||||||
($ty:ident) => {
|
($ty:ident) => {
|
||||||
|
@ -70,23 +56,6 @@ macro_rules! do_impl {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::UpperHex::fmt(&self.0, f) }
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::UpperHex::fmt(&self.0, f) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Into<u64>> Mul<T> for $ty {
|
|
||||||
type Output = $ty;
|
|
||||||
#[inline]
|
|
||||||
fn mul(self, rhs: T) -> Self { $ty(self.0 * rhs) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_int_mul!($ty, u8, u16, u32, u64);
|
|
||||||
|
|
||||||
impl<T: Into<u128>> Div<T> for $ty {
|
|
||||||
type Output = $ty;
|
|
||||||
#[inline]
|
|
||||||
fn div(self, rhs: T) -> Self {
|
|
||||||
let rhs = U256::from(rhs.into());
|
|
||||||
$ty(self.0 / rhs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -719,32 +688,6 @@ impl Mul for U256 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Into<u64>> Mul<T> for U256 {
|
|
||||||
type Output = Self;
|
|
||||||
fn mul(self, rhs: T) -> Self {
|
|
||||||
let (res, overflow) = self.mul_u64(rhs.into());
|
|
||||||
debug_assert!(!overflow, "U256 multiplied by integer overflowed");
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implements mul by unsigned int in both directions. Requires `u64::from($int)`.
|
|
||||||
macro_rules! impl_int_mul_u256 {
|
|
||||||
($($int:ident),+ $(,)?) => {
|
|
||||||
$(
|
|
||||||
impl Mul<U256> for $int {
|
|
||||||
type Output = U256;
|
|
||||||
fn mul(self, rhs: U256) -> U256 {
|
|
||||||
let (res, overflow) = rhs.mul_u64(u64::from(self));
|
|
||||||
debug_assert!(!overflow, "Integer multiplied by U256 overflowed");
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)+
|
|
||||||
};
|
|
||||||
}
|
|
||||||
impl_int_mul_u256!(u8, u16, u32, u64);
|
|
||||||
|
|
||||||
impl Div for U256 {
|
impl Div for U256 {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
fn div(self, rhs: Self) -> Self { self.div_rem(rhs).0 }
|
fn div(self, rhs: Self) -> Self { self.div_rem(rhs).0 }
|
||||||
|
@ -1653,26 +1596,10 @@ mod tests {
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn u256_overflowing_subtraction_panics() { let _ = U256::ZERO - U256::ONE; }
|
fn u256_overflowing_subtraction_panics() { let _ = U256::ZERO - U256::ONE; }
|
||||||
|
|
||||||
// We only test with test case value on the right hand side of the multiplication but that
|
#[test]
|
||||||
// should be enough coverage since we call the same underlying method to do multiplication with
|
#[should_panic]
|
||||||
// the sides inverted.
|
fn u256_multiplication_by_max_panics() {
|
||||||
macro_rules! test_u256_multiplication_panics {
|
let _ = U256::MAX * U256::MAX;
|
||||||
($($test_name:ident, $x:expr);* $(;)?) => {
|
|
||||||
$(
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
fn $test_name() {
|
|
||||||
let _ = U256::MAX * $x;
|
|
||||||
}
|
|
||||||
)*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
test_u256_multiplication_panics! {
|
|
||||||
u256_multiplication_by_max, U256::MAX;
|
|
||||||
u256_multiplication_by_u8, 2_u8;
|
|
||||||
u256_multiplication_by_u16, 2_u16;
|
|
||||||
u256_multiplication_by_u32, 2_u32;
|
|
||||||
u256_multiplication_by_u64, 2_u64;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1682,25 +1609,6 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn work_overflowing_subtraction_panics() { let _ = Work(U256::ZERO) - Work(U256::ONE); }
|
fn work_overflowing_subtraction_panics() { let _ = Work(U256::ZERO) - Work(U256::ONE); }
|
||||||
|
|
||||||
// Just test Work since Target is implemented using the same macro.
|
|
||||||
macro_rules! test_u256_multiplication_panics {
|
|
||||||
($($test_name:ident, $x:expr);* $(;)?) => {
|
|
||||||
$(
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
fn $test_name() {
|
|
||||||
let _ = Work(U256::MAX) * $x;
|
|
||||||
}
|
|
||||||
)*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
test_u256_multiplication_panics! {
|
|
||||||
work_multiplication_by_u8, 2_u8;
|
|
||||||
work_multiplication_by_u16, 2_u16;
|
|
||||||
work_multiplication_by_u32, 2_u32;
|
|
||||||
work_multiplication_by_u64, 2_u64;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(kani)]
|
#[cfg(kani)]
|
||||||
|
|
Loading…
Reference in New Issue