Skip to content

Commit

Permalink
Make overflow behaviour explicit for Timestamp
Browse files Browse the repository at this point in the history
  • Loading branch information
webmaster128 committed Apr 10, 2024
1 parent bbb788d commit b265b33
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 3 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ and this project adheres to
custom message type ([#2099])
- cosmwasm-std: Add `Uint{64,128,256,512}::panicking_add` and `::panicking_sub`
which are like the `Add`/`Sub` implementations but `const`.
- cosmwasm-std: Let `Timestamp::minus_nanos` use `Uint64::panicking_sub` and
document panicking behaviour.
- cosmwasm-std: Let `Timestamp::plus_nanos`/`::minus_nanos` use
`Uint64::panicking_add`/`::panicking_sub` and document panicking behaviour.

[#1983]: https://github.com/CosmWasm/cosmwasm/pull/1983
[#2057]: https://github.com/CosmWasm/cosmwasm/pull/2057
Expand Down
29 changes: 28 additions & 1 deletion packages/std/src/timestamp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,34 +37,54 @@ impl Timestamp {
Timestamp(Uint64::new(seconds_since_epoch * 1_000_000_000))
}

/// Adds the given amount of days to the timestamp and
/// returns the result. The original value remains unchanged.
///
/// Panics if the result exceeds the value range of [`Timestamp`].
#[must_use = "this returns the result of the operation, without modifying the original"]
#[inline]
pub const fn plus_days(&self, addition: u64) -> Timestamp {
self.plus_hours(addition * 24)
}

/// Adds the given amount of hours to the timestamp and
/// returns the result. The original value remains unchanged.
///
/// Panics if the result exceeds the value range of [`Timestamp`].
#[must_use = "this returns the result of the operation, without modifying the original"]
#[inline]
pub const fn plus_hours(&self, addition: u64) -> Timestamp {
self.plus_minutes(addition * 60)
}

/// Adds the given amount of minutes to the timestamp and
/// returns the result. The original value remains unchanged.
///
/// Panics if the result exceeds the value range of [`Timestamp`].
#[must_use = "this returns the result of the operation, without modifying the original"]
#[inline]
pub const fn plus_minutes(&self, addition: u64) -> Timestamp {
self.plus_seconds(addition * 60)
}

/// Adds the given amount of seconds to the timestamp and
/// returns the result. The original value remains unchanged.
///
/// Panics if the result exceeds the value range of [`Timestamp`].
#[must_use = "this returns the result of the operation, without modifying the original"]
#[inline]
pub const fn plus_seconds(&self, addition: u64) -> Timestamp {
self.plus_nanos(addition * 1_000_000_000)
}

/// Adds the given amount of nanoseconds to the timestamp and
/// returns the result. The original value remains unchanged.
///
/// Panics if the result exceeds the value range of [`Timestamp`].
#[must_use = "this returns the result of the operation, without modifying the original"]
// no #[inline] here as this could be shared with all the callers
pub const fn plus_nanos(&self, addition: u64) -> Timestamp {
let nanos = Uint64::new(self.0.u64() + addition);
let nanos = self.0.panicking_add(Uint64::new(addition));
Timestamp(nanos)
}

Expand Down Expand Up @@ -182,6 +202,13 @@ mod tests {
assert_eq!(sum.0.u64(), 123);
}

#[test]
#[should_panic(expected = "attempt to add with overflow")]
fn timestamp_plus_nanos_panics_on_overflow() {
let max = Timestamp::from_nanos(u64::MAX);
let _earlier = max.plus_nanos(20);
}

#[test]
fn timestamp_minus_seconds() {
let earlier = Timestamp::from_seconds(123).minus_seconds(0);
Expand Down

0 comments on commit b265b33

Please sign in to comment.