From c3b7457f6c92a3404c2d95d800773c02ac0dfc5f Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Thu, 8 May 2025 04:41:41 +1000 Subject: [PATCH] Rename Mtp to MedianTimePast Favour expressiveness over terseness for `units::locktime::absolute::Mtp` (formerly `Time`) because in general locktimes are curly AF. --- bitcoin/src/blockdata/mod.rs | 6 +-- bitcoin/src/blockdata/transaction.rs | 6 +-- primitives/src/locktime/absolute.rs | 28 +++++----- units/src/block.rs | 12 ++--- units/src/locktime/absolute.rs | 80 ++++++++++++++-------------- units/tests/api.rs | 10 ++-- units/tests/serde.rs | 4 +- 7 files changed, 73 insertions(+), 73 deletions(-) diff --git a/bitcoin/src/blockdata/mod.rs b/bitcoin/src/blockdata/mod.rs index 8255e3cc5..fa6f1502e 100644 --- a/bitcoin/src/blockdata/mod.rs +++ b/bitcoin/src/blockdata/mod.rs @@ -41,11 +41,11 @@ pub mod locktime { /// Re-export everything from the `primitives::locktime::absolute` module. #[rustfmt::skip] // Keep public re-exports separate. - pub use primitives::locktime::absolute::{ConversionError, Height, LockTime, ParseHeightError, ParseTimeError, Mtp}; + pub use primitives::locktime::absolute::{ConversionError, Height, LockTime, ParseHeightError, ParseTimeError, MedianTimePast}; - #[deprecated(since = "TBD", note = "use `Mtp` instead")] + #[deprecated(since = "TBD", note = "use `MedianTimePast` instead")] #[doc(hidden)] - pub type Time = Mtp; + pub type Time = MedianTimePast; impl Encodable for LockTime { #[inline] diff --git a/bitcoin/src/blockdata/transaction.rs b/bitcoin/src/blockdata/transaction.rs index 0c9772fa5..5c8360a3d 100644 --- a/bitcoin/src/blockdata/transaction.rs +++ b/bitcoin/src/blockdata/transaction.rs @@ -20,7 +20,7 @@ use primitives::Sequence; use super::Weight; use crate::consensus::{self, encode, Decodable, Encodable}; use crate::internal_macros::{impl_consensus_encoding, impl_hashencode}; -use crate::locktime::absolute::{self, Height, Mtp}; +use crate::locktime::absolute::{self, Height, MedianTimePast}; use crate::prelude::{Borrow, Vec}; use crate::script::{Script, ScriptBuf, ScriptExt as _, ScriptExtPriv as _}; #[cfg(doc)] @@ -295,7 +295,7 @@ pub trait TransactionExt: sealed::Sealed { /// By definition if the lock time is not enabled the transaction's absolute timelock is /// considered to be satisfied i.e., there are no timelock constraints restricting this /// transaction from being mined immediately. - fn is_absolute_timelock_satisfied(&self, height: Height, time: Mtp) -> bool; + fn is_absolute_timelock_satisfied(&self, height: Height, time: MedianTimePast) -> bool; /// Returns `true` if this transactions nLockTime is enabled ([BIP-65]). /// @@ -393,7 +393,7 @@ impl TransactionExt for Transaction { fn is_explicitly_rbf(&self) -> bool { self.input.iter().any(|input| input.sequence.is_rbf()) } - fn is_absolute_timelock_satisfied(&self, height: Height, time: Mtp) -> bool { + fn is_absolute_timelock_satisfied(&self, height: Height, time: MedianTimePast) -> bool { if !self.is_lock_time_enabled() { return true; } diff --git a/primitives/src/locktime/absolute.rs b/primitives/src/locktime/absolute.rs index fff858a19..c10d2ff79 100644 --- a/primitives/src/locktime/absolute.rs +++ b/primitives/src/locktime/absolute.rs @@ -16,11 +16,11 @@ use crate::{absolute, Transaction}; #[rustfmt::skip] // Keep public re-exports separate. #[doc(inline)] -pub use units::locktime::absolute::{ConversionError, Height, ParseHeightError, ParseTimeError, Mtp, LOCK_TIME_THRESHOLD}; +pub use units::locktime::absolute::{ConversionError, Height, ParseHeightError, ParseTimeError, MedianTimePast, LOCK_TIME_THRESHOLD}; -#[deprecated(since = "TBD", note = "use `Mtp` instead")] +#[deprecated(since = "TBD", note = "use `MedianTimePast` instead")] #[doc(hidden)] -pub type Time = Mtp; +pub type Time = MedianTimePast; /// An absolute lock time value, representing either a block height or a UNIX timestamp (seconds /// since epoch). @@ -83,7 +83,7 @@ pub enum LockTime { /// assert!(n.is_block_time()); /// assert_eq!(n.to_consensus_u32(), seconds); /// ``` - Seconds(Mtp), + Seconds(MedianTimePast), } impl LockTime { @@ -147,7 +147,7 @@ impl LockTime { if units::locktime::absolute::is_block_height(n) { Self::Blocks(Height::from_u32(n).expect("n is valid")) } else { - Self::Seconds(Mtp::from_u32(n).expect("n is valid")) + Self::Seconds(MedianTimePast::from_u32(n).expect("n is valid")) } } @@ -202,7 +202,7 @@ impl LockTime { /// ``` #[inline] pub fn from_mtp(n: u32) -> Result { - let time = Mtp::from_u32(n)?; + let time = MedianTimePast::from_u32(n)?; Ok(LockTime::Seconds(time)) } @@ -239,7 +239,7 @@ impl LockTime { /// # use bitcoin_primitives::absolute; /// // Can be implemented if block chain data is available. /// fn get_height() -> absolute::Height { todo!("return the current block height") } - /// fn get_time() -> absolute::Mtp { todo!("return the current block time") } + /// fn get_time() -> absolute::MedianTimePast { todo!("return the current block time") } /// /// let n = absolute::LockTime::from_consensus(741521); // `n OP_CHEKCLOCKTIMEVERIFY`. /// if n.is_satisfied_by(get_height(), get_time()) { @@ -247,7 +247,7 @@ impl LockTime { /// } /// ```` #[inline] - pub fn is_satisfied_by(self, height: Height, time: Mtp) -> bool { + pub fn is_satisfied_by(self, height: Height, time: MedianTimePast) -> bool { use LockTime as L; match self { @@ -333,9 +333,9 @@ impl From for LockTime { fn from(h: Height) -> Self { LockTime::Blocks(h) } } -impl From for LockTime { +impl From for LockTime { #[inline] - fn from(t: Mtp) -> Self { LockTime::Seconds(t) } + fn from(t: MedianTimePast) -> Self { LockTime::Seconds(t) } } impl fmt::Debug for LockTime { @@ -512,7 +512,7 @@ mod tests { let lock_by_height = LockTime::from(height); let t: u32 = 1_653_195_600; // May 22nd, 5am UTC. - let time = Mtp::from_u32(t).unwrap(); + let time = MedianTimePast::from_u32(t).unwrap(); assert!(!lock_by_height.is_satisfied_by(height_below, time)); assert!(lock_by_height.is_satisfied_by(height, time)); @@ -521,9 +521,9 @@ mod tests { #[test] fn satisfied_by_time() { - let time_before = Mtp::from_u32(1_653_109_200).unwrap(); // "May 21th 2022, 5am UTC. - let time = Mtp::from_u32(1_653_195_600).unwrap(); // "May 22nd 2022, 5am UTC. - let time_after = Mtp::from_u32(1_653_282_000).unwrap(); // "May 23rd 2022, 5am UTC. + let time_before = MedianTimePast::from_u32(1_653_109_200).unwrap(); // "May 21th 2022, 5am UTC. + let time = MedianTimePast::from_u32(1_653_195_600).unwrap(); // "May 22nd 2022, 5am UTC. + let time_after = MedianTimePast::from_u32(1_653_282_000).unwrap(); // "May 23rd 2022, 5am UTC. let lock_by_time = LockTime::from(time); diff --git a/units/src/block.rs b/units/src/block.rs index dcb483f1c..351fbe63f 100644 --- a/units/src/block.rs +++ b/units/src/block.rs @@ -171,7 +171,7 @@ impl_u32_wrapper! { /// The median timestamp of 11 consecutive blocks. /// /// This type is not meant for constructing time-based timelocks. It is a general purpose - /// MTP abstraction. For locktimes please see [`locktime::absolute::Mtp`]. + /// MTP abstraction. For locktimes please see [`locktime::absolute::MedianTimePast`]. /// /// This is a thin wrapper around a `u32` that may take on all values of a `u32`. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -202,22 +202,22 @@ impl BlockMtp { } } -impl From for BlockMtp { - /// Converts a [`locktime::absolute::Mtp`] to a [`BlockMtp`]. +impl From for BlockMtp { + /// Converts a [`locktime::absolute::MedianTimePast`] to a [`BlockMtp`]. /// /// An absolute locktime MTP has a minimum value of [`absolute::LOCK_TIME_THRESHOLD`], /// while [`BlockMtp`] may take the full range of `u32`. - fn from(h: absolute::Mtp) -> Self { Self::from_u32(h.to_u32()) } + fn from(h: absolute::MedianTimePast) -> Self { Self::from_u32(h.to_u32()) } } -impl TryFrom for absolute::Mtp { +impl TryFrom for absolute::MedianTimePast { type Error = absolute::ConversionError; /// Converts a [`BlockHeight`] to a [`locktime::absolute::Height`]. /// /// An absolute locktime MTP has a minimum value of [`absolute::LOCK_TIME_THRESHOLD`], /// while [`BlockMtp`] may take the full range of `u32`. - fn try_from(h: BlockMtp) -> Result { absolute::Mtp::from_u32(h.to_u32()) } + fn try_from(h: BlockMtp) -> Result { absolute::MedianTimePast::from_u32(h.to_u32()) } } impl_u32_wrapper! { diff --git a/units/src/locktime/absolute.rs b/units/src/locktime/absolute.rs index 214d048a1..e44d8f364 100644 --- a/units/src/locktime/absolute.rs +++ b/units/src/locktime/absolute.rs @@ -1,6 +1,6 @@ // SPDX-License-Identifier: CC0-1.0 -//! Provides [`Height`] and [`Mtp`] types used by the `rust-bitcoin` `absolute::LockTime` type. +//! Provides [`Height`] and [`MedianTimePast`] types used by the `rust-bitcoin` `absolute::LockTime` type. use core::convert::Infallible; use core::fmt; @@ -132,9 +132,9 @@ impl serde::Serialize for Height { } } -#[deprecated(since = "TBD", note = "use `Mtp` instead")] +#[deprecated(since = "TBD", note = "use `MedianTimePast` instead")] #[doc(hidden)] -pub type Time = Mtp; +pub type Time = MedianTimePast; /// The median timestamp of 11 consecutive blocks, representing "the timestamp" of the /// final block for locktime-checking purposes. @@ -145,16 +145,16 @@ pub type Time = Mtp; /// a quantity which is required by consensus to be monotone and which is difficult /// for any individual miner to manipulate. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct Mtp(u32); +pub struct MedianTimePast(u32); -impl Mtp { +impl MedianTimePast { /// The minimum MTP allowable in a locktime (Tue Nov 05 1985 00:53:20 GMT+0000). - pub const MIN: Self = Mtp(LOCK_TIME_THRESHOLD); + pub const MIN: Self = MedianTimePast(LOCK_TIME_THRESHOLD); /// The maximum MTP allowable in a locktime (Sun Feb 07 2106 06:28:15 GMT+0000). - pub const MAX: Self = Mtp(u32::MAX); + pub const MAX: Self = MedianTimePast(u32::MAX); - /// Constructs an [`Mtp`] by computing the median‐time‐past from the last 11 block timestamps + /// Constructs an [`MedianTimePast`] by computing the median‐time‐past from the last 11 block timestamps /// /// Because block timestamps are not monotonic, this function internally sorts them; /// it is therefore not important what order they appear in the array; use whatever @@ -170,7 +170,7 @@ impl Mtp { crate::BlockMtp::new(timestamps).try_into() } - /// Constructs a new [`Mtp`] from a big-endian hex-encoded `u32`. + /// Constructs a new [`MedianTimePast`] from a big-endian hex-encoded `u32`. /// /// The input string may or may not contain a typical hex prefix e.g., `0x`. /// @@ -189,7 +189,7 @@ impl Mtp { /// Constructs a new MTP directly from a `u32` value. /// - /// This function, with [`Mtp::to_u32`], is used to obtain a raw MTP value. It is + /// This function, with [`MedianTimePast::to_u32`], is used to obtain a raw MTP value. It is /// **not** used to convert to or from a block timestamp, which is not a MTP. /// /// # Errors @@ -199,10 +199,10 @@ impl Mtp { /// # Examples /// /// ```rust - /// use bitcoin_units::locktime::absolute::Mtp; + /// use bitcoin_units::locktime::absolute::MedianTimePast; /// /// let t: u32 = 1653195600; // May 22nd, 5am UTC. - /// let time = Mtp::from_u32(t).expect("invalid time value"); + /// let time = MedianTimePast::from_u32(t).expect("invalid time value"); /// assert_eq!(time.to_consensus_u32(), t); /// ``` #[inline] @@ -214,30 +214,30 @@ impl Mtp { } } - /// Converts this [`Mtp`] to a raw `u32` value. + /// Converts this [`MedianTimePast`] to a raw `u32` value. #[inline] pub const fn to_u32(self) -> u32 { self.0 } } -impl fmt::Display for Mtp { +impl fmt::Display for MedianTimePast { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) } } -crate::impl_parse_str!(Mtp, ParseTimeError, parser(Mtp::from_u32)); +crate::impl_parse_str!(MedianTimePast, ParseTimeError, parser(MedianTimePast::from_u32)); #[cfg(feature = "serde")] -impl<'de> serde::Deserialize<'de> for Mtp { +impl<'de> serde::Deserialize<'de> for MedianTimePast { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { let u = u32::deserialize(deserializer)?; - Mtp::from_u32(u).map_err(serde::de::Error::custom) + MedianTimePast::from_u32(u).map_err(serde::de::Error::custom) } } #[cfg(feature = "serde")] -impl serde::Serialize for Mtp { +impl serde::Serialize for MedianTimePast { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, @@ -383,11 +383,11 @@ impl ParseError { E::ParseInt(ParseIntError { input, bits: _, is_signed: _, source }) if *source.kind() == IntErrorKind::PosOverflow => { - // Outputs "failed to parse as absolute Height/Mtp ( is above limit )" + // Outputs "failed to parse as absolute Height/MedianTimePast ( is above limit )" write!( f, "{} ({} is above limit {})", - input.display_cannot_parse("absolute Height/Mtp"), + input.display_cannot_parse("absolute Height/MedianTimePast"), subject, upper_bound ) @@ -395,17 +395,17 @@ impl ParseError { E::ParseInt(ParseIntError { input, bits: _, is_signed: _, source }) if *source.kind() == IntErrorKind::NegOverflow => { - // Outputs "failed to parse as absolute Height/Mtp ( is below limit )" + // Outputs "failed to parse as absolute Height/MedianTimePast ( is below limit )" write!( f, "{} ({} is below limit {})", - input.display_cannot_parse("absolute Height/Mtp"), + input.display_cannot_parse("absolute Height/MedianTimePast"), subject, lower_bound ) } E::ParseInt(ParseIntError { input, bits: _, is_signed: _, source: _ }) => { - write!(f, "{} ({})", input.display_cannot_parse("absolute Height/Mtp"), subject) + write!(f, "{} ({})", input.display_cannot_parse("absolute Height/MedianTimePast"), subject) } E::Conversion(value) if *value < i64::from(lower_bound) => { write!(f, "{} {} is below limit {}", subject, value, lower_bound) @@ -458,17 +458,17 @@ impl<'a> Arbitrary<'a> for Height { } #[cfg(feature = "arbitrary")] -impl<'a> Arbitrary<'a> for Mtp { +impl<'a> Arbitrary<'a> for MedianTimePast { fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result { let choice = u.int_in_range(0..=2)?; match choice { - 0 => Ok(Mtp::MIN), - 1 => Ok(Mtp::MAX), + 0 => Ok(MedianTimePast::MIN), + 1 => Ok(MedianTimePast::MAX), _ => { - let min = Mtp::MIN.to_u32(); - let max = Mtp::MAX.to_u32(); + let min = MedianTimePast::MIN.to_u32(); + let max = MedianTimePast::MAX.to_u32(); let t = u.int_in_range(min..=max)?; - Ok(Mtp::from_u32(t).unwrap()) + Ok(MedianTimePast::from_u32(t).unwrap()) } } } @@ -483,21 +483,21 @@ mod tests { #[test] fn time_from_str_hex_happy_path() { - let actual = Mtp::from_hex("0x6289C350").unwrap(); - let expected = Mtp::from_u32(0x6289_C350).unwrap(); + let actual = MedianTimePast::from_hex("0x6289C350").unwrap(); + let expected = MedianTimePast::from_u32(0x6289_C350).unwrap(); assert_eq!(actual, expected); } #[test] fn time_from_str_hex_no_prefix_happy_path() { - let time = Mtp::from_hex("6289C350").unwrap(); - assert_eq!(time, Mtp(0x6289_C350)); + let time = MedianTimePast::from_hex("6289C350").unwrap(); + assert_eq!(time, MedianTimePast(0x6289_C350)); } #[test] fn time_from_str_hex_invalid_hex_should_err() { let hex = "0xzb93"; - let result = Mtp::from_hex(hex); + let result = MedianTimePast::from_hex(hex); assert!(result.is_err()); } @@ -541,8 +541,8 @@ mod tests { #[test] #[cfg(feature = "serde")] pub fn encode_decode_time() { - serde_round_trip!(Mtp::MIN); - serde_round_trip!(Mtp::MAX); + serde_round_trip!(MedianTimePast::MIN); + serde_round_trip!(MedianTimePast::MAX); } #[test] @@ -575,12 +575,12 @@ mod tests { ]; // Try various reorderings - assert_eq!(Mtp::new(timestamps).unwrap().to_u32(), 500_000_005); + assert_eq!(MedianTimePast::new(timestamps).unwrap().to_u32(), 500_000_005); timestamps.reverse(); - assert_eq!(Mtp::new(timestamps).unwrap().to_u32(), 500_000_005); + assert_eq!(MedianTimePast::new(timestamps).unwrap().to_u32(), 500_000_005); timestamps.sort(); - assert_eq!(Mtp::new(timestamps).unwrap().to_u32(), 500_000_005); + assert_eq!(MedianTimePast::new(timestamps).unwrap().to_u32(), 500_000_005); timestamps.reverse(); - assert_eq!(Mtp::new(timestamps).unwrap().to_u32(), 500_000_005); + assert_eq!(MedianTimePast::new(timestamps).unwrap().to_u32(), 500_000_005); } } diff --git a/units/tests/api.rs b/units/tests/api.rs index a1956d10a..5ce217b75 100644 --- a/units/tests/api.rs +++ b/units/tests/api.rs @@ -38,7 +38,7 @@ struct Structs { e: BlockInterval, f: FeeRate, g: absolute::Height, - h: absolute::Mtp, + h: absolute::MedianTimePast, i: relative::Height, j: relative::Time, k: Weight, @@ -57,7 +57,7 @@ impl Structs { e: BlockInterval::MAX, f: FeeRate::MAX, g: absolute::Height::MAX, - h: absolute::Mtp::MAX, + h: absolute::MedianTimePast::MAX, i: relative::Height::MAX, j: relative::Time::MAX, k: Weight::MAX, @@ -89,7 +89,7 @@ struct CommonTraits { e: BlockInterval, f: FeeRate, g: absolute::Height, - h: absolute::Mtp, + h: absolute::MedianTimePast, i: relative::Height, j: relative::Time, k: Weight, @@ -184,7 +184,7 @@ fn api_can_use_all_types_from_module_fee_rate() { #[test] fn api_can_use_all_types_from_module_locktime_absolute() { use bitcoin_units::locktime::absolute::{ - ConversionError, Height, Mtp, ParseHeightError, ParseTimeError, + ConversionError, Height, MedianTimePast, ParseHeightError, ParseTimeError, }; } @@ -302,7 +302,7 @@ impl<'a> Arbitrary<'a> for Structs { e: BlockInterval::arbitrary(u)?, f: FeeRate::arbitrary(u)?, g: absolute::Height::arbitrary(u)?, - h: absolute::Mtp::arbitrary(u)?, + h: absolute::MedianTimePast::arbitrary(u)?, i: relative::Height::arbitrary(u)?, j: relative::Time::arbitrary(u)?, k: Weight::arbitrary(u)?, diff --git a/units/tests/serde.rs b/units/tests/serde.rs index 24cf9b047..e6c7d0af6 100644 --- a/units/tests/serde.rs +++ b/units/tests/serde.rs @@ -47,7 +47,7 @@ struct Serde { a: BlockHeight, b: BlockInterval, c: absolute::Height, - d: absolute::Mtp, + d: absolute::MedianTimePast, e: relative::Height, f: relative::Time, g: Weight, @@ -80,7 +80,7 @@ impl Serde { a: BlockHeight::MAX, b: BlockInterval::MAX, c: absolute::Height::MAX, - d: absolute::Mtp::MAX, + d: absolute::MedianTimePast::MAX, e: relative::Height::MAX, f: relative::Time::MAX, g: Weight::MAX,