Rename MtpInterval to NumberOf512Seconds
Name the type exactly what it is. This used to be `Time`, then we tried `MtpInterval`. Note that this makes some of the original function names overly verbose e.g., `NumberOf512seconds::from_512_second_intervals()` but given the curlyness of locktimes too verbose is better than too terse. Also this type, along with `NumberOfBlocks` is not going to be in very wide use so the ergonomic hit is worth the additional clarity.
This commit is contained in:
parent
3a97ea2259
commit
7c2115b68f
|
@ -72,16 +72,16 @@ pub mod locktime {
|
||||||
/// Re-export everything from the `primitives::locktime::relative` module.
|
/// Re-export everything from the `primitives::locktime::relative` module.
|
||||||
pub use primitives::locktime::relative::{
|
pub use primitives::locktime::relative::{
|
||||||
DisabledLockTimeError, NumberOfBlocks, IncompatibleHeightError, IncompatibleTimeError,
|
DisabledLockTimeError, NumberOfBlocks, IncompatibleHeightError, IncompatibleTimeError,
|
||||||
LockTime, MtpInterval, TimeOverflowError,
|
LockTime, NumberOf512Seconds, TimeOverflowError,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[deprecated(since = "TBD", note = "use `NumberOfBlocks` instead")]
|
#[deprecated(since = "TBD", note = "use `NumberOfBlocks` instead")]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub type Height = NumberOfBlocks;
|
pub type Height = NumberOfBlocks;
|
||||||
|
|
||||||
#[deprecated(since = "TBD", note = "use `Mtp` instead")]
|
#[deprecated(since = "TBD", note = "use `NumberOf512Seconds` instead")]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub type Time = MtpInterval;
|
pub type Time = NumberOf512Seconds;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,16 +13,16 @@ use crate::{relative, TxIn};
|
||||||
|
|
||||||
#[rustfmt::skip] // Keep public re-exports separate.
|
#[rustfmt::skip] // Keep public re-exports separate.
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use units::locktime::relative::{NumberOfBlocks, MtpInterval, TimeOverflowError};
|
pub use units::locktime::relative::{NumberOfBlocks, NumberOf512Seconds, TimeOverflowError};
|
||||||
use units::{BlockHeight, BlockMtp};
|
use units::{BlockHeight, BlockMtp};
|
||||||
|
|
||||||
#[deprecated(since = "TBD", note = "use `NumberOfBlocks` instead")]
|
#[deprecated(since = "TBD", note = "use `NumberOfBlocks` instead")]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub type Height = NumberOfBlocks;
|
pub type Height = NumberOfBlocks;
|
||||||
|
|
||||||
#[deprecated(since = "TBD", note = "use `Mtp` instead")]
|
#[deprecated(since = "TBD", note = "use `NumberOf512Seconds` instead")]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub type Time = MtpInterval;
|
pub type Time = NumberOf512Seconds;
|
||||||
|
|
||||||
/// A relative lock time value, representing either a block height or time (512 second intervals).
|
/// A relative lock time value, representing either a block height or time (512 second intervals).
|
||||||
///
|
///
|
||||||
|
@ -68,7 +68,7 @@ pub type Time = MtpInterval;
|
||||||
/// let utxo_height = BlockHeight::from(80);
|
/// let utxo_height = BlockHeight::from(80);
|
||||||
/// let utxo_mtp = BlockMtp::new(utxo_timestamps);
|
/// let utxo_mtp = BlockMtp::new(utxo_timestamps);
|
||||||
///
|
///
|
||||||
/// let locktime = relative::LockTime::Time(relative::MtpInterval::from_512_second_intervals(10));
|
/// let locktime = relative::LockTime::Time(relative::NumberOf512Seconds::from_512_second_intervals(10));
|
||||||
///
|
///
|
||||||
/// // Check if locktime is satisfied
|
/// // Check if locktime is satisfied
|
||||||
/// assert!(locktime.is_satisfied_by(current_height, current_mtp, utxo_height, utxo_mtp));
|
/// assert!(locktime.is_satisfied_by(current_height, current_mtp, utxo_height, utxo_mtp));
|
||||||
|
@ -79,7 +79,7 @@ pub enum LockTime {
|
||||||
/// A block height lock time value.
|
/// A block height lock time value.
|
||||||
Blocks(NumberOfBlocks),
|
Blocks(NumberOfBlocks),
|
||||||
/// A 512 second time interval value.
|
/// A 512 second time interval value.
|
||||||
Time(MtpInterval),
|
Time(NumberOf512Seconds),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LockTime {
|
impl LockTime {
|
||||||
|
@ -172,7 +172,7 @@ impl LockTime {
|
||||||
/// [`Self::from_seconds_floor`] or [`Self::from_seconds_ceil`].
|
/// [`Self::from_seconds_floor`] or [`Self::from_seconds_ceil`].
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn from_512_second_intervals(intervals: u16) -> Self {
|
pub const fn from_512_second_intervals(intervals: u16) -> Self {
|
||||||
LockTime::Time(MtpInterval::from_512_second_intervals(intervals))
|
LockTime::Time(NumberOf512Seconds::from_512_second_intervals(intervals))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a new [`LockTime`] from seconds, converting the seconds into 512 second interval
|
/// Construct a new [`LockTime`] from seconds, converting the seconds into 512 second interval
|
||||||
|
@ -183,7 +183,7 @@ impl LockTime {
|
||||||
/// Will return an error if the input cannot be encoded in 16 bits.
|
/// Will return an error if the input cannot be encoded in 16 bits.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn from_seconds_floor(seconds: u32) -> Result<Self, TimeOverflowError> {
|
pub const fn from_seconds_floor(seconds: u32) -> Result<Self, TimeOverflowError> {
|
||||||
match MtpInterval::from_seconds_floor(seconds) {
|
match NumberOf512Seconds::from_seconds_floor(seconds) {
|
||||||
Ok(time) => Ok(LockTime::Time(time)),
|
Ok(time) => Ok(LockTime::Time(time)),
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,7 @@ impl LockTime {
|
||||||
/// Will return an error if the input cannot be encoded in 16 bits.
|
/// Will return an error if the input cannot be encoded in 16 bits.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn from_seconds_ceil(seconds: u32) -> Result<Self, TimeOverflowError> {
|
pub const fn from_seconds_ceil(seconds: u32) -> Result<Self, TimeOverflowError> {
|
||||||
match MtpInterval::from_seconds_ceil(seconds) {
|
match NumberOf512Seconds::from_seconds_ceil(seconds) {
|
||||||
Ok(time) => Ok(LockTime::Time(time)),
|
Ok(time) => Ok(LockTime::Time(time)),
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
}
|
}
|
||||||
|
@ -378,7 +378,7 @@ impl LockTime {
|
||||||
/// assert!(lock.is_satisfied_by_time(relative::Time::from_512_second_intervals(intervals + 10)).expect("a time"));
|
/// assert!(lock.is_satisfied_by_time(relative::Time::from_512_second_intervals(intervals + 10)).expect("a time"));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_satisfied_by_time(self, time: MtpInterval) -> Result<bool, IncompatibleTimeError> {
|
pub fn is_satisfied_by_time(self, time: NumberOf512Seconds) -> Result<bool, IncompatibleTimeError> {
|
||||||
use LockTime as L;
|
use LockTime as L;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
|
@ -393,9 +393,9 @@ impl From<NumberOfBlocks> for LockTime {
|
||||||
fn from(h: NumberOfBlocks) -> Self { LockTime::Blocks(h) }
|
fn from(h: NumberOfBlocks) -> Self { LockTime::Blocks(h) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<MtpInterval> for LockTime {
|
impl From<NumberOf512Seconds> for LockTime {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(t: MtpInterval) -> Self { LockTime::Time(t) }
|
fn from(t: NumberOf512Seconds) -> Self { LockTime::Time(t) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for LockTime {
|
impl fmt::Display for LockTime {
|
||||||
|
@ -457,7 +457,7 @@ pub struct IncompatibleHeightError {
|
||||||
/// Attempted to satisfy a lock-by-blocktime lock with this height.
|
/// Attempted to satisfy a lock-by-blocktime lock with this height.
|
||||||
height: NumberOfBlocks,
|
height: NumberOfBlocks,
|
||||||
/// The inner time value of the lock-by-blocktime lock.
|
/// The inner time value of the lock-by-blocktime lock.
|
||||||
time: MtpInterval,
|
time: NumberOf512Seconds,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IncompatibleHeightError {
|
impl IncompatibleHeightError {
|
||||||
|
@ -465,7 +465,7 @@ impl IncompatibleHeightError {
|
||||||
pub fn incompatible(&self) -> NumberOfBlocks { self.height }
|
pub fn incompatible(&self) -> NumberOfBlocks { self.height }
|
||||||
|
|
||||||
/// Returns the time value of the lock-by-blocktime lock.
|
/// Returns the time value of the lock-by-blocktime lock.
|
||||||
pub fn expected(&self) -> MtpInterval { self.time }
|
pub fn expected(&self) -> NumberOf512Seconds { self.time }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for IncompatibleHeightError {
|
impl fmt::Display for IncompatibleHeightError {
|
||||||
|
@ -486,14 +486,14 @@ impl std::error::Error for IncompatibleHeightError {}
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct IncompatibleTimeError {
|
pub struct IncompatibleTimeError {
|
||||||
/// Attempted to satisfy a lock-by-blockheight lock with this time.
|
/// Attempted to satisfy a lock-by-blockheight lock with this time.
|
||||||
time: MtpInterval,
|
time: NumberOf512Seconds,
|
||||||
/// The inner height value of the lock-by-blockheight lock.
|
/// The inner height value of the lock-by-blockheight lock.
|
||||||
height: NumberOfBlocks,
|
height: NumberOfBlocks,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IncompatibleTimeError {
|
impl IncompatibleTimeError {
|
||||||
/// Returns the time that was erroneously used to try and satisfy a lock-by-blockheight lock.
|
/// Returns the time that was erroneously used to try and satisfy a lock-by-blockheight lock.
|
||||||
pub fn incompatible(&self) -> MtpInterval { self.time }
|
pub fn incompatible(&self) -> NumberOf512Seconds { self.time }
|
||||||
|
|
||||||
/// Returns the height value of the lock-by-blockheight lock.
|
/// Returns the height value of the lock-by-blockheight lock.
|
||||||
pub fn expected(&self) -> NumberOfBlocks { self.height }
|
pub fn expected(&self) -> NumberOfBlocks { self.height }
|
||||||
|
@ -553,8 +553,8 @@ mod tests {
|
||||||
fn parses_correctly_to_height_or_time() {
|
fn parses_correctly_to_height_or_time() {
|
||||||
let height1 = NumberOfBlocks::from(10);
|
let height1 = NumberOfBlocks::from(10);
|
||||||
let height2 = NumberOfBlocks::from(11);
|
let height2 = NumberOfBlocks::from(11);
|
||||||
let time1 = MtpInterval::from_512_second_intervals(70);
|
let time1 = NumberOf512Seconds::from_512_second_intervals(70);
|
||||||
let time2 = MtpInterval::from_512_second_intervals(71);
|
let time2 = NumberOf512Seconds::from_512_second_intervals(71);
|
||||||
|
|
||||||
let lock_by_height1 = LockTime::from(height1);
|
let lock_by_height1 = LockTime::from(height1);
|
||||||
let lock_by_height2 = LockTime::from(height2);
|
let lock_by_height2 = LockTime::from(height2);
|
||||||
|
@ -586,24 +586,24 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn time_correctly_implies() {
|
fn time_correctly_implies() {
|
||||||
let time = MtpInterval::from_512_second_intervals(70);
|
let time = NumberOf512Seconds::from_512_second_intervals(70);
|
||||||
let lock_by_time = LockTime::from(time);
|
let lock_by_time = LockTime::from(time);
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
!lock_by_time.is_implied_by(LockTime::from(MtpInterval::from_512_second_intervals(69)))
|
!lock_by_time.is_implied_by(LockTime::from(NumberOf512Seconds::from_512_second_intervals(69)))
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
lock_by_time.is_implied_by(LockTime::from(MtpInterval::from_512_second_intervals(70)))
|
lock_by_time.is_implied_by(LockTime::from(NumberOf512Seconds::from_512_second_intervals(70)))
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
lock_by_time.is_implied_by(LockTime::from(MtpInterval::from_512_second_intervals(71)))
|
lock_by_time.is_implied_by(LockTime::from(NumberOf512Seconds::from_512_second_intervals(71)))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sequence_correctly_implies() {
|
fn sequence_correctly_implies() {
|
||||||
let height = NumberOfBlocks::from(10);
|
let height = NumberOfBlocks::from(10);
|
||||||
let time = MtpInterval::from_512_second_intervals(70);
|
let time = NumberOf512Seconds::from_512_second_intervals(70);
|
||||||
|
|
||||||
let lock_by_height = LockTime::from(height);
|
let lock_by_height = LockTime::from(height);
|
||||||
let lock_by_time = LockTime::from(time);
|
let lock_by_time = LockTime::from(time);
|
||||||
|
@ -624,7 +624,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn incorrect_units_do_not_imply() {
|
fn incorrect_units_do_not_imply() {
|
||||||
let time = MtpInterval::from_512_second_intervals(70);
|
let time = NumberOf512Seconds::from_512_second_intervals(70);
|
||||||
let height = NumberOfBlocks::from(10);
|
let height = NumberOfBlocks::from(10);
|
||||||
|
|
||||||
let lock_by_time = LockTime::from(time);
|
let lock_by_time = LockTime::from(time);
|
||||||
|
@ -665,7 +665,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn incompatible_height_error() {
|
fn incompatible_height_error() {
|
||||||
let height = NumberOfBlocks::from(10);
|
let height = NumberOfBlocks::from(10);
|
||||||
let time = MtpInterval::from_512_second_intervals(70);
|
let time = NumberOf512Seconds::from_512_second_intervals(70);
|
||||||
let lock_by_time = LockTime::from(time);
|
let lock_by_time = LockTime::from(time);
|
||||||
let err = lock_by_time.is_satisfied_by_height(height).unwrap_err();
|
let err = lock_by_time.is_satisfied_by_height(height).unwrap_err();
|
||||||
|
|
||||||
|
@ -677,7 +677,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn incompatible_time_error() {
|
fn incompatible_time_error() {
|
||||||
let height = NumberOfBlocks::from(10);
|
let height = NumberOfBlocks::from(10);
|
||||||
let time = MtpInterval::from_512_second_intervals(70);
|
let time = NumberOf512Seconds::from_512_second_intervals(70);
|
||||||
let lock_by_height = LockTime::from(height);
|
let lock_by_height = LockTime::from(height);
|
||||||
let err = lock_by_height.is_satisfied_by_time(time).unwrap_err();
|
let err = lock_by_height.is_satisfied_by_time(time).unwrap_err();
|
||||||
|
|
||||||
|
@ -710,10 +710,10 @@ mod tests {
|
||||||
let lock2 = LockTime::Blocks(NumberOfBlocks::from(21));
|
let lock2 = LockTime::Blocks(NumberOfBlocks::from(21));
|
||||||
assert!(!lock2.is_satisfied_by(chain_height, chain_mtp, utxo_height, utxo_mtp));
|
assert!(!lock2.is_satisfied_by(chain_height, chain_mtp, utxo_height, utxo_mtp));
|
||||||
|
|
||||||
let lock3 = LockTime::Time(MtpInterval::from_512_second_intervals(10));
|
let lock3 = LockTime::Time(NumberOf512Seconds::from_512_second_intervals(10));
|
||||||
assert!(lock3.is_satisfied_by(chain_height, chain_mtp, utxo_height, utxo_mtp));
|
assert!(lock3.is_satisfied_by(chain_height, chain_mtp, utxo_height, utxo_mtp));
|
||||||
|
|
||||||
let lock4 = LockTime::Time(MtpInterval::from_512_second_intervals(20000));
|
let lock4 = LockTime::Time(NumberOf512Seconds::from_512_second_intervals(20000));
|
||||||
assert!(!lock4.is_satisfied_by(chain_height, chain_mtp, utxo_height, utxo_mtp));
|
assert!(!lock4.is_satisfied_by(chain_height, chain_mtp, utxo_height, utxo_mtp));
|
||||||
|
|
||||||
assert!(LockTime::ZERO.is_satisfied_by(chain_height, chain_mtp, utxo_height, utxo_mtp));
|
assert!(LockTime::ZERO.is_satisfied_by(chain_height, chain_mtp, utxo_height, utxo_mtp));
|
||||||
|
@ -730,7 +730,7 @@ mod tests {
|
||||||
let max_height_lock = LockTime::Blocks(NumberOfBlocks::MAX);
|
let max_height_lock = LockTime::Blocks(NumberOfBlocks::MAX);
|
||||||
assert!(!max_height_lock.is_satisfied_by(chain_height, chain_mtp, utxo_height, utxo_mtp));
|
assert!(!max_height_lock.is_satisfied_by(chain_height, chain_mtp, utxo_height, utxo_mtp));
|
||||||
|
|
||||||
let max_time_lock = LockTime::Time(MtpInterval::MAX);
|
let max_time_lock = LockTime::Time(NumberOf512Seconds::MAX);
|
||||||
assert!(!max_time_lock.is_satisfied_by(chain_height, chain_mtp, utxo_height, utxo_mtp));
|
assert!(!max_time_lock.is_satisfied_by(chain_height, chain_mtp, utxo_height, utxo_mtp));
|
||||||
|
|
||||||
let max_chain_height = BlockHeight::from_u32(u32::MAX);
|
let max_chain_height = BlockHeight::from_u32(u32::MAX);
|
||||||
|
|
|
@ -187,7 +187,7 @@ impl Sequence {
|
||||||
/// Constructs a new [`relative::LockTime`] from this [`Sequence`] number.
|
/// Constructs a new [`relative::LockTime`] from this [`Sequence`] number.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_relative_lock_time(self) -> Option<relative::LockTime> {
|
pub fn to_relative_lock_time(self) -> Option<relative::LockTime> {
|
||||||
use crate::locktime::relative::{NumberOfBlocks, LockTime, MtpInterval};
|
use crate::locktime::relative::{NumberOfBlocks, LockTime, NumberOf512Seconds};
|
||||||
|
|
||||||
if !self.is_relative_lock_time() {
|
if !self.is_relative_lock_time() {
|
||||||
return None;
|
return None;
|
||||||
|
@ -196,7 +196,7 @@ impl Sequence {
|
||||||
let lock_value = self.low_u16();
|
let lock_value = self.low_u16();
|
||||||
|
|
||||||
if self.is_time_locked() {
|
if self.is_time_locked() {
|
||||||
Some(LockTime::from(MtpInterval::from_512_second_intervals(lock_value)))
|
Some(LockTime::from(NumberOf512Seconds::from_512_second_intervals(lock_value)))
|
||||||
} else {
|
} else {
|
||||||
Some(LockTime::from(NumberOfBlocks::from(lock_value)))
|
Some(LockTime::from(NumberOfBlocks::from(lock_value)))
|
||||||
}
|
}
|
||||||
|
@ -265,11 +265,11 @@ impl<'a> Arbitrary<'a> for Sequence {
|
||||||
5 => Ok(Sequence::from_consensus(u32::from(relative::NumberOfBlocks::MAX.to_height()))),
|
5 => Ok(Sequence::from_consensus(u32::from(relative::NumberOfBlocks::MAX.to_height()))),
|
||||||
6 => Ok(Sequence::from_consensus(
|
6 => Ok(Sequence::from_consensus(
|
||||||
Sequence::LOCK_TYPE_MASK
|
Sequence::LOCK_TYPE_MASK
|
||||||
| u32::from(relative::MtpInterval::MIN.to_512_second_intervals()),
|
| u32::from(relative::NumberOf512Seconds::MIN.to_512_second_intervals()),
|
||||||
)),
|
)),
|
||||||
7 => Ok(Sequence::from_consensus(
|
7 => Ok(Sequence::from_consensus(
|
||||||
Sequence::LOCK_TYPE_MASK
|
Sequence::LOCK_TYPE_MASK
|
||||||
| u32::from(relative::MtpInterval::MAX.to_512_second_intervals()),
|
| u32::from(relative::NumberOf512Seconds::MAX.to_512_second_intervals()),
|
||||||
)),
|
)),
|
||||||
_ => Ok(Sequence(u.arbitrary()?)),
|
_ => Ok(Sequence(u.arbitrary()?)),
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,7 +224,7 @@ impl_u32_wrapper! {
|
||||||
/// An unsigned difference between two [`BlockMtp`]s.
|
/// An unsigned difference between two [`BlockMtp`]s.
|
||||||
///
|
///
|
||||||
/// This type is not meant for constructing time-based timelocks. It is a general purpose
|
/// This type is not meant for constructing time-based timelocks. It is a general purpose
|
||||||
/// MTP abstraction. For locktimes please see [`locktime::relative::MtpInterval`].
|
/// MTP abstraction. For locktimes please see [`locktime::relative::NumberOf512Seconds`].
|
||||||
///
|
///
|
||||||
/// This is a thin wrapper around a `u32` that may take on all values of a `u32`.
|
/// This is a thin wrapper around a `u32` that may take on all values of a `u32`.
|
||||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
@ -234,7 +234,7 @@ impl_u32_wrapper! {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlockMtpInterval {
|
impl BlockMtpInterval {
|
||||||
/// Converts a [`BlockMtpInterval`] to a [`locktime::relative::MtpInterval`], rounding down.
|
/// Converts a [`BlockMtpInterval`] to a [`locktime::relative::NumberOf512Seconds`], rounding down.
|
||||||
///
|
///
|
||||||
/// Relative timelock MTP intervals have a resolution of 512 seconds, while
|
/// Relative timelock MTP intervals have a resolution of 512 seconds, while
|
||||||
/// [`BlockMtpInterval`], like all block timestamp types, has a one-second resolution.
|
/// [`BlockMtpInterval`], like all block timestamp types, has a one-second resolution.
|
||||||
|
@ -246,11 +246,11 @@ impl BlockMtpInterval {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn to_relative_mtp_interval_floor(
|
pub const fn to_relative_mtp_interval_floor(
|
||||||
self,
|
self,
|
||||||
) -> Result<relative::MtpInterval, relative::TimeOverflowError> {
|
) -> Result<relative::NumberOf512Seconds, relative::TimeOverflowError> {
|
||||||
relative::MtpInterval::from_seconds_floor(self.to_u32())
|
relative::NumberOf512Seconds::from_seconds_floor(self.to_u32())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a [`BlockMtpInterval`] to a [`locktime::relative::MtpInterval`], rounding up.
|
/// Converts a [`BlockMtpInterval`] to a [`locktime::relative::NumberOf512Seconds`], rounding up.
|
||||||
///
|
///
|
||||||
/// Relative timelock MTP intervals have a resolution of 512 seconds, while
|
/// Relative timelock MTP intervals have a resolution of 512 seconds, while
|
||||||
/// [`BlockMtpInterval`], like all block timestamp types, has a one-second resolution.
|
/// [`BlockMtpInterval`], like all block timestamp types, has a one-second resolution.
|
||||||
|
@ -262,8 +262,8 @@ impl BlockMtpInterval {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn to_relative_mtp_interval_ceil(
|
pub const fn to_relative_mtp_interval_ceil(
|
||||||
self,
|
self,
|
||||||
) -> Result<relative::MtpInterval, relative::TimeOverflowError> {
|
) -> Result<relative::NumberOf512Seconds, relative::TimeOverflowError> {
|
||||||
relative::MtpInterval::from_seconds_ceil(self.to_u32())
|
relative::NumberOf512Seconds::from_seconds_ceil(self.to_u32())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempt to subtract two [`BlockMtpInterval`]s, returning `None` in case of overflow.
|
/// Attempt to subtract two [`BlockMtpInterval`]s, returning `None` in case of overflow.
|
||||||
|
@ -273,13 +273,13 @@ impl BlockMtpInterval {
|
||||||
pub fn checked_add(self, other: Self) -> Option<Self> { self.0.checked_add(other.0).map(Self) }
|
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::NumberOf512Seconds> for BlockMtpInterval {
|
||||||
/// Converts a [`locktime::relative::MtpInterval`] to a [`BlockMtpInterval `].
|
/// Converts a [`locktime::relative::NumberOf512Seconds`] to a [`BlockMtpInterval `].
|
||||||
///
|
///
|
||||||
/// A relative locktime MTP interval has a resolution of 512 seconds, and a maximum value
|
/// A relative locktime MTP interval has a resolution of 512 seconds, and a maximum value
|
||||||
/// of `u16::MAX` 512-second intervals. [`BlockMtpInterval`] may take the full range of
|
/// of `u16::MAX` 512-second intervals. [`BlockMtpInterval`] may take the full range of
|
||||||
/// `u32`.
|
/// `u32`.
|
||||||
fn from(h: relative::MtpInterval) -> Self { Self::from_u32(h.to_seconds()) }
|
fn from(h: relative::NumberOf512Seconds) -> Self { Self::from_u32(h.to_seconds()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Error returned when the block interval is too big to be used as a relative lock time.
|
/// Error returned when the block interval is too big to be used as a relative lock time.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// SPDX-License-Identifier: CC0-1.0
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
//! Provides [`NumberOfBlocks`] and [`MtpInterval`] types used by the `rust-bitcoin` `relative::LockTime` type.
|
//! Provides [`NumberOfBlocks`] and [`NumberOf512Seconds`] types used by the `rust-bitcoin` `relative::LockTime` type.
|
||||||
|
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
|
||||||
|
@ -91,39 +91,39 @@ impl fmt::Display for NumberOfBlocks {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deprecated(since = "TBD", note = "use `Mtp` instead")]
|
#[deprecated(since = "TBD", note = "use `NumberOf512Seconds` instead")]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub type Time = MtpInterval;
|
pub type Time = NumberOf512Seconds;
|
||||||
|
|
||||||
/// A relative lock time lock-by-blocktime value.
|
/// A relative lock time lock-by-blocktime value.
|
||||||
///
|
///
|
||||||
/// For BIP 68 relative lock-by-blocktime locks, time is measured in 512 second intervals.
|
/// For BIP 68 relative lock-by-blocktime locks, time is measured in 512 second intervals.
|
||||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
pub struct MtpInterval(u16);
|
pub struct NumberOf512Seconds(u16);
|
||||||
|
|
||||||
impl MtpInterval {
|
impl NumberOf512Seconds {
|
||||||
/// Relative block time 0, can be included in any block.
|
/// Relative block time 0, can be included in any block.
|
||||||
pub const ZERO: Self = MtpInterval(0);
|
pub const ZERO: Self = NumberOf512Seconds(0);
|
||||||
|
|
||||||
/// The minimum relative block time (0), can be included in any block.
|
/// The minimum relative block time (0), can be included in any block.
|
||||||
pub const MIN: Self = MtpInterval::ZERO;
|
pub const MIN: Self = NumberOf512Seconds::ZERO;
|
||||||
|
|
||||||
/// The maximum relative block time (33,554,432 seconds or approx 388 days).
|
/// The maximum relative block time (33,554,432 seconds or approx 388 days).
|
||||||
pub const MAX: Self = MtpInterval(u16::MAX);
|
pub const MAX: Self = NumberOf512Seconds(u16::MAX);
|
||||||
|
|
||||||
/// Constructs a new [`MtpInterval`] using time intervals where each interval is equivalent to 512 seconds.
|
/// Constructs a new [`NumberOf512Seconds`] using time intervals where each interval is equivalent to 512 seconds.
|
||||||
///
|
///
|
||||||
/// Encoding finer granularity of time for relative lock-times is not supported in Bitcoin.
|
/// Encoding finer granularity of time for relative lock-times is not supported in Bitcoin.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn from_512_second_intervals(intervals: u16) -> Self { MtpInterval(intervals) }
|
pub const fn from_512_second_intervals(intervals: u16) -> Self { NumberOf512Seconds(intervals) }
|
||||||
|
|
||||||
/// Express the [`MtpInterval`] as an integer number of 512-second intervals.
|
/// Express the [`NumberOf512Seconds`] as an integer number of 512-second intervals.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn to_512_second_intervals(self) -> u16 { self.0 }
|
pub const fn to_512_second_intervals(self) -> u16 { self.0 }
|
||||||
|
|
||||||
/// Constructs a new [`MtpInterval`] from seconds, converting the seconds into 512 second interval with
|
/// Constructs a new [`NumberOf512Seconds`] from seconds, converting the seconds into 512 second interval with
|
||||||
/// truncating division.
|
/// truncating division.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
|
@ -134,13 +134,13 @@ impl MtpInterval {
|
||||||
pub const fn from_seconds_floor(seconds: u32) -> Result<Self, TimeOverflowError> {
|
pub const fn from_seconds_floor(seconds: u32) -> Result<Self, TimeOverflowError> {
|
||||||
let interval = seconds / 512;
|
let interval = seconds / 512;
|
||||||
if interval <= u16::MAX as u32 { // infallible cast, needed by const code
|
if interval <= u16::MAX as u32 { // infallible cast, needed by const code
|
||||||
Ok(MtpInterval::from_512_second_intervals(interval as u16)) // Cast checked above, needed by const code.
|
Ok(NumberOf512Seconds::from_512_second_intervals(interval as u16)) // Cast checked above, needed by const code.
|
||||||
} else {
|
} else {
|
||||||
Err(TimeOverflowError { seconds })
|
Err(TimeOverflowError { seconds })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a new [`MtpInterval`] from seconds, converting the seconds into 512 second intervals with
|
/// Constructs a new [`NumberOf512Seconds`] from seconds, converting the seconds into 512 second intervals with
|
||||||
/// ceiling division.
|
/// ceiling division.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
|
@ -151,13 +151,13 @@ impl MtpInterval {
|
||||||
pub const fn from_seconds_ceil(seconds: u32) -> Result<Self, TimeOverflowError> {
|
pub const fn from_seconds_ceil(seconds: u32) -> Result<Self, TimeOverflowError> {
|
||||||
if seconds <= u16::MAX as u32 * 512 {
|
if seconds <= u16::MAX as u32 * 512 {
|
||||||
let interval = (seconds + 511) / 512;
|
let interval = (seconds + 511) / 512;
|
||||||
Ok(MtpInterval::from_512_second_intervals(interval as u16)) // Cast checked above, needed by const code.
|
Ok(NumberOf512Seconds::from_512_second_intervals(interval as u16)) // Cast checked above, needed by const code.
|
||||||
} else {
|
} else {
|
||||||
Err(TimeOverflowError { seconds })
|
Err(TimeOverflowError { seconds })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents the [`MtpInterval`] as an integer number of seconds.
|
/// Represents the [`NumberOf512Seconds`] as an integer number of seconds.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn to_seconds(self) -> u32 {
|
pub const fn to_seconds(self) -> u32 {
|
||||||
self.0 as u32 * 512 // u16->u32 cast ok, const context
|
self.0 as u32 * 512 // u16->u32 cast ok, const context
|
||||||
|
@ -206,9 +206,9 @@ impl MtpInterval {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::impl_parse_str_from_int_infallible!(MtpInterval, u16, from_512_second_intervals);
|
crate::impl_parse_str_from_int_infallible!(NumberOf512Seconds, u16, from_512_second_intervals);
|
||||||
|
|
||||||
impl fmt::Display for MtpInterval {
|
impl fmt::Display for NumberOf512Seconds {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,14 +259,14 @@ impl<'a> Arbitrary<'a> for NumberOfBlocks {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "arbitrary")]
|
#[cfg(feature = "arbitrary")]
|
||||||
impl<'a> Arbitrary<'a> for MtpInterval {
|
impl<'a> Arbitrary<'a> for NumberOf512Seconds {
|
||||||
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
|
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
|
||||||
let choice = u.int_in_range(0..=2)?;
|
let choice = u.int_in_range(0..=2)?;
|
||||||
|
|
||||||
match choice {
|
match choice {
|
||||||
0 => Ok(MtpInterval::MIN),
|
0 => Ok(NumberOf512Seconds::MIN),
|
||||||
1 => Ok(MtpInterval::MAX),
|
1 => Ok(NumberOf512Seconds::MAX),
|
||||||
_ => Ok(MtpInterval::from_512_second_intervals(u16::arbitrary(u)?)),
|
_ => Ok(NumberOf512Seconds::from_512_second_intervals(u16::arbitrary(u)?)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -285,54 +285,54 @@ mod tests {
|
||||||
#[allow(deprecated_in_future)]
|
#[allow(deprecated_in_future)]
|
||||||
fn sanity_check() {
|
fn sanity_check() {
|
||||||
assert_eq!(NumberOfBlocks::MAX.to_consensus_u32(), u32::from(u16::MAX));
|
assert_eq!(NumberOfBlocks::MAX.to_consensus_u32(), u32::from(u16::MAX));
|
||||||
assert_eq!(MtpInterval::from_512_second_intervals(100).value(), 100u16);
|
assert_eq!(NumberOf512Seconds::from_512_second_intervals(100).value(), 100u16);
|
||||||
assert_eq!(MtpInterval::from_512_second_intervals(100).to_consensus_u32(), 4_194_404u32); // 0x400064
|
assert_eq!(NumberOf512Seconds::from_512_second_intervals(100).to_consensus_u32(), 4_194_404u32); // 0x400064
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn from_seconds_ceil_success() {
|
fn from_seconds_ceil_success() {
|
||||||
let actual = MtpInterval::from_seconds_ceil(100).unwrap();
|
let actual = NumberOf512Seconds::from_seconds_ceil(100).unwrap();
|
||||||
let expected = MtpInterval(1_u16);
|
let expected = NumberOf512Seconds(1_u16);
|
||||||
assert_eq!(actual, expected);
|
assert_eq!(actual, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn from_seconds_ceil_with_maximum_encodable_seconds_success() {
|
fn from_seconds_ceil_with_maximum_encodable_seconds_success() {
|
||||||
let actual = MtpInterval::from_seconds_ceil(MAXIMUM_ENCODABLE_SECONDS).unwrap();
|
let actual = NumberOf512Seconds::from_seconds_ceil(MAXIMUM_ENCODABLE_SECONDS).unwrap();
|
||||||
let expected = MtpInterval(u16::MAX);
|
let expected = NumberOf512Seconds(u16::MAX);
|
||||||
assert_eq!(actual, expected);
|
assert_eq!(actual, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn from_seconds_ceil_causes_time_overflow_error() {
|
fn from_seconds_ceil_causes_time_overflow_error() {
|
||||||
let result = MtpInterval::from_seconds_ceil(MAXIMUM_ENCODABLE_SECONDS + 1);
|
let result = NumberOf512Seconds::from_seconds_ceil(MAXIMUM_ENCODABLE_SECONDS + 1);
|
||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn from_seconds_floor_success() {
|
fn from_seconds_floor_success() {
|
||||||
let actual = MtpInterval::from_seconds_floor(100).unwrap();
|
let actual = NumberOf512Seconds::from_seconds_floor(100).unwrap();
|
||||||
let expected = MtpInterval(0_u16);
|
let expected = NumberOf512Seconds(0_u16);
|
||||||
assert_eq!(actual, expected);
|
assert_eq!(actual, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn from_seconds_floor_with_exact_interval() {
|
fn from_seconds_floor_with_exact_interval() {
|
||||||
let actual = MtpInterval::from_seconds_floor(512).unwrap();
|
let actual = NumberOf512Seconds::from_seconds_floor(512).unwrap();
|
||||||
let expected = MtpInterval(1_u16);
|
let expected = NumberOf512Seconds(1_u16);
|
||||||
assert_eq!(actual, expected);
|
assert_eq!(actual, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn from_seconds_floor_with_maximum_encodable_seconds_success() {
|
fn from_seconds_floor_with_maximum_encodable_seconds_success() {
|
||||||
let actual = MtpInterval::from_seconds_floor(MAXIMUM_ENCODABLE_SECONDS + 511).unwrap();
|
let actual = NumberOf512Seconds::from_seconds_floor(MAXIMUM_ENCODABLE_SECONDS + 511).unwrap();
|
||||||
let expected = MtpInterval(u16::MAX);
|
let expected = NumberOf512Seconds(u16::MAX);
|
||||||
assert_eq!(actual, expected);
|
assert_eq!(actual, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn from_seconds_floor_causes_time_overflow_error() {
|
fn from_seconds_floor_causes_time_overflow_error() {
|
||||||
let result = MtpInterval::from_seconds_floor(MAXIMUM_ENCODABLE_SECONDS + 512);
|
let result = NumberOf512Seconds::from_seconds_floor(MAXIMUM_ENCODABLE_SECONDS + 512);
|
||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,9 +347,9 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
pub fn encode_decode_time() {
|
pub fn encode_decode_time() {
|
||||||
serde_round_trip!(MtpInterval::ZERO);
|
serde_round_trip!(NumberOf512Seconds::ZERO);
|
||||||
serde_round_trip!(MtpInterval::MIN);
|
serde_round_trip!(NumberOf512Seconds::MIN);
|
||||||
serde_round_trip!(MtpInterval::MAX);
|
serde_round_trip!(NumberOf512Seconds::MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_timestamps(start: u32, step: u16) -> [BlockTime; 11] {
|
fn generate_timestamps(start: u32, step: u16) -> [BlockTime; 11] {
|
||||||
|
@ -375,7 +375,7 @@ mod tests {
|
||||||
|
|
||||||
// Test case 1: Satisfaction (current_mtp >= utxo_mtp + required_seconds)
|
// Test case 1: Satisfaction (current_mtp >= utxo_mtp + required_seconds)
|
||||||
// 10 intervals × 512 seconds = 5120 seconds
|
// 10 intervals × 512 seconds = 5120 seconds
|
||||||
let time_lock = MtpInterval::from_512_second_intervals(10);
|
let time_lock = NumberOf512Seconds::from_512_second_intervals(10);
|
||||||
let chain_state1 = BlockMtp::new(timestamps);
|
let chain_state1 = BlockMtp::new(timestamps);
|
||||||
let utxo_state1 = BlockMtp::new(utxo_timestamps);
|
let utxo_state1 = BlockMtp::new(utxo_timestamps);
|
||||||
assert!(time_lock.is_satisfied_by(chain_state1, utxo_state1));
|
assert!(time_lock.is_satisfied_by(chain_state1, utxo_state1));
|
||||||
|
@ -386,13 +386,13 @@ mod tests {
|
||||||
assert!(!time_lock.is_satisfied_by(chain_state2, utxo_state2));
|
assert!(!time_lock.is_satisfied_by(chain_state2, utxo_state2));
|
||||||
|
|
||||||
// Test case 3: Test with a larger value (100 intervals = 51200 seconds)
|
// Test case 3: Test with a larger value (100 intervals = 51200 seconds)
|
||||||
let larger_lock = MtpInterval::from_512_second_intervals(100);
|
let larger_lock = NumberOf512Seconds::from_512_second_intervals(100);
|
||||||
let chain_state3 = BlockMtp::new(timestamps3);
|
let chain_state3 = BlockMtp::new(timestamps3);
|
||||||
let utxo_state3 = BlockMtp::new(utxo_timestamps3);
|
let utxo_state3 = BlockMtp::new(utxo_timestamps3);
|
||||||
assert!(larger_lock.is_satisfied_by(chain_state3, utxo_state3));
|
assert!(larger_lock.is_satisfied_by(chain_state3, utxo_state3));
|
||||||
|
|
||||||
// Test case 4: Overflow handling - tests that is_satisfied_by handles overflow gracefully
|
// Test case 4: Overflow handling - tests that is_satisfied_by handles overflow gracefully
|
||||||
let max_time_lock = MtpInterval::MAX;
|
let max_time_lock = NumberOf512Seconds::MAX;
|
||||||
let chain_state4 = BlockMtp::new(timestamps);
|
let chain_state4 = BlockMtp::new(timestamps);
|
||||||
let utxo_state4 = BlockMtp::new(utxo_timestamps);
|
let utxo_state4 = BlockMtp::new(utxo_timestamps);
|
||||||
assert!(!max_time_lock.is_satisfied_by(chain_state4, utxo_state4));
|
assert!(!max_time_lock.is_satisfied_by(chain_state4, utxo_state4));
|
||||||
|
|
Loading…
Reference in New Issue