units: add checked arithmetic to Block{Height,Mtp}{Interval,}

This commit is contained in:
Andrew Poelstra 2025-05-06 15:32:16 +00:00
parent 4300271f0c
commit dcbdb7ca8a
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
1 changed files with 36 additions and 0 deletions

View File

@ -89,6 +89,18 @@ impl_u32_wrapper! {
pub struct BlockHeight(pub u32); pub struct BlockHeight(pub u32);
} }
impl BlockHeight {
/// Attempt to subtract two [`BlockHeight`]s, returning `None` in case of overflow.
pub fn checked_sub(self, other: Self) -> Option<BlockHeightInterval> {
self.0.checked_sub(other.0).map(BlockHeightInterval)
}
/// Attempt to add an interval to this [`BlockHeight`], returning `None` in case of overflow.
pub fn checked_add(self, other: BlockHeightInterval) -> Option<Self> {
self.0.checked_add(other.0).map(Self)
}
}
impl From<absolute::Height> for BlockHeight { impl From<absolute::Height> for BlockHeight {
/// Converts a [`locktime::absolute::Height`] to a [`BlockHeight`]. /// Converts a [`locktime::absolute::Height`] to a [`BlockHeight`].
/// ///
@ -122,6 +134,14 @@ impl_u32_wrapper! {
pub struct BlockHeightInterval(pub u32); pub struct BlockHeightInterval(pub u32);
} }
impl BlockHeightInterval {
/// Attempt to subtract two [`BlockHeightInterval`]s, returning `None` in case of overflow.
pub fn checked_sub(self, other: Self) -> Option<Self> { self.0.checked_sub(other.0).map(Self) }
/// Attempt to add two [`BlockHeightInterval`]s, returning `None` in case of overflow.
pub fn checked_add(self, other: Self) -> Option<Self> { self.0.checked_add(other.0).map(Self) }
}
impl From<relative::HeightInterval> for BlockHeightInterval { impl From<relative::HeightInterval> for BlockHeightInterval {
/// Converts a [`locktime::relative::HeightInterval`] to a [`BlockHeightInterval`]. /// Converts a [`locktime::relative::HeightInterval`] to a [`BlockHeightInterval`].
/// ///
@ -170,6 +190,16 @@ impl BlockMtp {
timestamps.sort_unstable(); timestamps.sort_unstable();
Self::from_u32(u32::from(timestamps[5])) Self::from_u32(u32::from(timestamps[5]))
} }
/// Attempt to subtract two [`BlockMtp`]s, returning `None` in case of overflow.
pub fn checked_sub(self, other: Self) -> Option<BlockMtpInterval> {
self.0.checked_sub(other.0).map(BlockMtpInterval)
}
/// Attempt to add an interval to this [`BlockMtp`], returning `None` in case of overflow.
pub fn checked_add(self, other: BlockMtpInterval) -> Option<Self> {
self.0.checked_add(other.0).map(Self)
}
} }
impl From<absolute::Mtp> for BlockMtp { impl From<absolute::Mtp> for BlockMtp {
@ -235,6 +265,12 @@ impl BlockMtpInterval {
) -> Result<relative::MtpInterval, relative::TimeOverflowError> { ) -> Result<relative::MtpInterval, relative::TimeOverflowError> {
relative::MtpInterval::from_seconds_ceil(self.to_u32()) relative::MtpInterval::from_seconds_ceil(self.to_u32())
} }
/// Attempt to subtract two [`BlockMtpInterval`]s, returning `None` in case of overflow.
pub fn checked_sub(self, other: Self) -> Option<Self> { self.0.checked_sub(other.0).map(Self) }
/// Attempt to add two [`BlockMtpInterval`]s, returning `None` in case of overflow.
pub fn checked_add(self, other: Self) -> Option<Self> { self.0.checked_add(other.0).map(Self) }
} }
impl From<relative::MtpInterval> for BlockMtpInterval { impl From<relative::MtpInterval> for BlockMtpInterval {