Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use newly added panicking_add/panicking_sub for Timestamp math (backport #2098) #2104

Merged
merged 7 commits into from
Apr 10, 2024
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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,13 @@ and this project adheres to
- cosmwasm-std: Implement `&T + T` and `&T op &T` for `Uint64`, `Uint128`,
`Uint256` and `Uint512`; improve panic message for `Uint64::add` and
`Uint512::add` ([#2092])
- cosmwasm-std: Add `Uint{64,128,256,512}::panicking_add` and `::panicking_sub`
which are like the `Add`/`Sub` implementations but `const`. ([#2098])
- cosmwasm-std: Let `Timestamp::plus_nanos`/`::minus_nanos` use
`Uint64::panicking_add`/`::panicking_sub` and document overflows. ([#2098])

[#2092]: https://github.com/CosmWasm/cosmwasm/pull/2092
[#2098]: https://github.com/CosmWasm/cosmwasm/pull/2098

### Fixed

Expand Down
49 changes: 39 additions & 10 deletions packages/std/src/math/uint128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,28 @@ impl Uint128 {
Self(self.0.saturating_pow(exp))
}

/// This is the same as [`Uint128::add`] but const.
///
/// Panics on overflow.
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn panicking_add(self, other: Self) -> Self {
match self.0.checked_add(other.u128()) {
None => panic!("attempt to add with overflow"),
Some(sum) => Self(sum),
}
}

/// This is the same as [`Uint128::sub`] but const.
///
/// Panics on overflow.
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn panicking_sub(self, other: Self) -> Self {
match self.0.checked_sub(other.u128()) {
None => panic!("attempt to subtract with overflow"),
Some(diff) => Self(diff),
}
}

#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn abs_diff(self, other: Self) -> Self {
Self(if self.0 < other.0 {
Expand Down Expand Up @@ -372,11 +394,7 @@ impl Add<Uint128> for Uint128 {
type Output = Self;

fn add(self, rhs: Self) -> Self {
Self(
self.u128()
.checked_add(rhs.u128())
.expect("attempt to add with overflow"),
)
self.panicking_add(rhs)
}
}
forward_ref_binop!(impl Add, add for Uint128, Uint128);
Expand All @@ -385,11 +403,7 @@ impl Sub<Uint128> for Uint128 {
type Output = Self;

fn sub(self, rhs: Self) -> Self {
Uint128(
self.u128()
.checked_sub(rhs.u128())
.expect("attempt to subtract with overflow"),
)
self.panicking_sub(rhs)
}
}
forward_ref_binop!(impl Sub, sub for Uint128, Uint128);
Expand Down Expand Up @@ -1178,6 +1192,21 @@ mod tests {
assert_eq!(a, Uint128::from(1u32));
}

#[test]
fn uint128_panicking_sub_works() {
let a = Uint128::new(5);
let b = Uint128::new(3);
assert_eq!(a.panicking_sub(b), Uint128::new(2));
}

#[test]
#[should_panic(expected = "attempt to subtract with overflow")]
fn uint128_panicking_sub_panics_on_overflow() {
let a = Uint128::ZERO;
let b = Uint128::ONE;
let _diff = a.panicking_sub(b);
}

#[test]
fn uint128_abs_diff_works() {
let a = Uint128::from(42u32);
Expand Down
49 changes: 39 additions & 10 deletions packages/std/src/math/uint256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,28 @@ impl Uint256 {
Self(self.0.saturating_pow(exp))
}

/// This is the same as [`Uint256::add`] but const.
///
/// Panics on overflow.
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn panicking_add(self, other: Self) -> Self {
match self.0.checked_add(other.0) {
None => panic!("attempt to add with overflow"),
Some(sum) => Self(sum),
}
}

/// This is the same as [`Uint256::sub`] but const.
///
/// Panics on overflow.
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn panicking_sub(self, other: Self) -> Self {
match self.0.checked_sub(other.0) {
None => panic!("attempt to subtract with overflow"),
Some(diff) => Self(diff),
}
}

#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn abs_diff(self, other: Self) -> Self {
Self(self.0.abs_diff(other.0))
Expand Down Expand Up @@ -440,11 +462,7 @@ impl Add<Uint256> for Uint256 {
type Output = Self;

fn add(self, rhs: Self) -> Self {
Self(
self.0
.checked_add(rhs.0)
.expect("attempt to add with overflow"),
)
self.panicking_add(rhs)
}
}
forward_ref_binop!(impl Add, add for Uint256, Uint256);
Expand All @@ -453,11 +471,7 @@ impl Sub<Uint256> for Uint256 {
type Output = Self;

fn sub(self, rhs: Self) -> Self {
Self(
self.0
.checked_sub(rhs.0)
.expect("attempt to subtract with overflow"),
)
self.panicking_sub(rhs)
}
}
forward_ref_binop!(impl Sub, sub for Uint256, Uint256);
Expand Down Expand Up @@ -1729,6 +1743,21 @@ mod tests {
assert_eq!(a, Uint256::from(1u32));
}

#[test]
fn uint256_panicking_sub_works() {
let a = Uint256::from(5u32);
let b = Uint256::from(3u32);
assert_eq!(a.panicking_sub(b), Uint256::from(2u32));
}

#[test]
#[should_panic(expected = "attempt to subtract with overflow")]
fn uint256_panicking_sub_panics_on_overflow() {
let a = Uint256::ZERO;
let b = Uint256::ONE;
let _diff = a.panicking_sub(b);
}

#[test]
fn uint256_abs_diff_works() {
let a = Uint256::from(42u32);
Expand Down
45 changes: 39 additions & 6 deletions packages/std/src/math/uint512.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,28 @@ impl Uint512 {
Self(self.0.saturating_pow(exp))
}

/// This is the same as [`Uint512::add`] but const.
///
/// Panics on overflow.
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn panicking_add(self, other: Self) -> Self {
match self.0.checked_add(other.0) {
None => panic!("attempt to add with overflow"),
Some(sum) => Self(sum),
}
}

/// This is the same as [`Uint512::sub`] but const.
///
/// Panics on overflow.
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn panicking_sub(self, other: Self) -> Self {
match self.0.checked_sub(other.0) {
None => panic!("attempt to subtract with overflow"),
Some(diff) => Self(diff),
}
}

#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn abs_diff(self, other: Self) -> Self {
Self(self.0.abs_diff(other.0))
Expand Down Expand Up @@ -424,11 +446,7 @@ impl Add<Uint512> for Uint512 {
type Output = Self;

fn add(self, rhs: Self) -> Self {
Self(
self.0
.checked_add(rhs.0)
.expect("attempt to add with overflow"),
)
self.panicking_add(rhs)
}
}
forward_ref_binop!(impl Add, add for Uint512, Uint512);
Expand All @@ -437,7 +455,7 @@ impl Sub<Uint512> for Uint512 {
type Output = Self;

fn sub(self, rhs: Self) -> Self {
Uint512(self.0.checked_sub(rhs.0).unwrap())
self.panicking_sub(rhs)
}
}
forward_ref_binop!(impl Sub, sub for Uint512, Uint512);
Expand Down Expand Up @@ -1379,6 +1397,21 @@ mod tests {
assert_eq!(a, Uint512::from(1u32));
}

#[test]
fn uint512_panicking_sub_works() {
let a = Uint512::from(5u32);
let b = Uint512::from(3u32);
assert_eq!(a.panicking_sub(b), Uint512::from(2u32));
}

#[test]
#[should_panic(expected = "attempt to subtract with overflow")]
fn uint512_panicking_sub_panics_on_overflow() {
let a = Uint512::ZERO;
let b = Uint512::ONE;
let _diff = a.panicking_sub(b);
}

#[test]
fn uint512_abs_diff_works() {
let a = Uint512::from(42u32);
Expand Down
49 changes: 39 additions & 10 deletions packages/std/src/math/uint64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,28 @@ impl Uint64 {
Self(self.0.saturating_pow(exp))
}

/// This is the same as [`Uint64::add`] but const.
///
/// Panics on overflow.
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn panicking_add(self, other: Self) -> Self {
match self.0.checked_add(other.u64()) {
None => panic!("attempt to add with overflow"),
Some(sum) => Self(sum),
}
}

/// This is the same as [`Uint64::sub`] but const.
///
/// Panics on overflow.
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn panicking_sub(self, other: Self) -> Self {
match self.0.checked_sub(other.u64()) {
None => panic!("attempt to subtract with overflow"),
Some(diff) => Self(diff),
}
}

#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn abs_diff(self, other: Self) -> Self {
Self(if self.0 < other.0 {
Expand Down Expand Up @@ -345,11 +367,7 @@ impl Add<Uint64> for Uint64 {
type Output = Self;

fn add(self, rhs: Self) -> Self {
Self(
self.u64()
.checked_add(rhs.u64())
.expect("attempt to add with overflow"),
)
self.panicking_add(rhs)
}
}
forward_ref_binop!(impl Add, add for Uint64, Uint64);
Expand All @@ -358,11 +376,7 @@ impl Sub<Uint64> for Uint64 {
type Output = Self;

fn sub(self, rhs: Self) -> Self {
Uint64(
self.u64()
.checked_sub(rhs.u64())
.expect("attempt to subtract with overflow"),
)
self.panicking_sub(rhs)
}
}
forward_ref_binop!(impl Sub, sub for Uint64, Uint64);
Expand Down Expand Up @@ -1090,6 +1104,21 @@ mod tests {
assert_eq!(a, Uint64::from(1u32));
}

#[test]
fn uint64_panicking_sub_works() {
let a = Uint64::new(5);
let b = Uint64::new(3);
assert_eq!(a.panicking_sub(b), Uint64::new(2));
}

#[test]
#[should_panic(expected = "attempt to subtract with overflow")]
fn uint64_panicking_sub_panics_on_overflow() {
let a = Uint64::ZERO;
let b = Uint64::ONE;
let _diff = a.panicking_sub(b);
}

#[test]
fn uint64_abs_diff_works() {
let a = Uint64::from(42u32);
Expand Down
Loading
Loading