From 25a67425739d1d29ccc75ba8ba6f631f111448d8 Mon Sep 17 00:00:00 2001 From: "Jamil Lambert, PhD" Date: Tue, 28 Jan 2025 15:19:13 +0000 Subject: [PATCH 1/3] Add examples to `relative::LockTime` --- primitives/src/locktime/relative.rs | 44 +++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/primitives/src/locktime/relative.rs b/primitives/src/locktime/relative.rs index 2c3fb0ad6..f37e49354 100644 --- a/primitives/src/locktime/relative.rs +++ b/primitives/src/locktime/relative.rs @@ -32,6 +32,23 @@ pub use units::locktime::relative::{Height, Time, TimeOverflowError}; /// /// * [BIP 68 Relative lock-time using consensus-enforced sequence numbers](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki) /// * [BIP 112 CHECKSEQUENCEVERIFY](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki) +/// +/// # Examples +/// +/// ``` +/// use bitcoin_primitives::relative::{LockTime, Height, Time}; +/// let lock_by_height = LockTime::from_height(144); // 144 blocks, approx 24h. +/// assert!(lock_by_height.is_block_height()); +/// +/// let lock_by_time = LockTime::from_512_second_intervals(168); // 168 time intervals, approx 24h. +/// assert!(lock_by_time.is_block_time()); +/// +/// // Check if a lock time is satisfied by a given height or time. +/// let height = Height::from(150); +/// let time = Time::from_512_second_intervals(200); +/// assert!(lock_by_height.is_satisfied_by(height, time)); +/// assert!(lock_by_time.is_satisfied_by(height, time)); +/// ``` #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum LockTime { @@ -89,6 +106,18 @@ impl LockTime { /// /// This method will **not** round-trip with [`Self::to_sequence`]. See the /// docs for [`Self::from_consensus`] for more information. + /// # Examples + /// + /// ```rust + /// # use bitcoin_primitives::{Sequence, relative::LockTime}; + /// + /// // Interpret a sequence number from a Bitcoin transaction input as a relative lock time + /// let sequence_number = Sequence::from_consensus(144); // 144 blocks, approx 24h. + /// let lock_time = LockTime::from_sequence(sequence_number)?; + /// assert!(lock_time.is_block_height()); + /// + /// # Ok::<_, bitcoin_primitives::relative::DisabledLockTimeError>(()) + /// ``` #[inline] pub fn from_sequence(n: Sequence) -> Result { Self::from_consensus(n.to_consensus_u32()) @@ -227,6 +256,21 @@ impl LockTime { /// When deciding whether an instance of ` CHECKSEQUENCEVERIFY` will pass, this /// method can be used by parsing `n` as a [`LockTime`] and calling this method /// with the sequence number of the input which spends the script. + /// + /// # Examples + /// + /// ``` + /// # use bitcoin_primitives::{Sequence, relative::LockTime}; + /// + /// let sequence = Sequence::from_consensus(1 << 22 | 168); // Bit 22 is 1 with time approx 24h. + /// let lock_time = LockTime::from_sequence(sequence)?; + /// let input_sequence = Sequence::from_consensus(1 << 22 | 336); // Approx 48h. + /// assert!(lock_time.is_block_time()); + /// + /// assert!(lock_time.is_implied_by_sequence(input_sequence)); + /// + /// # Ok::<_, bitcoin_primitives::relative::DisabledLockTimeError>(()) + /// ``` #[inline] pub fn is_implied_by_sequence(&self, other: Sequence) -> bool { if let Ok(other) = LockTime::from_sequence(other) { From 2d73746ad1cd4536b84d174b6410c75ab187bdcf Mon Sep 17 00:00:00 2001 From: "Jamil Lambert, PhD" Date: Tue, 28 Jan 2025 15:44:45 +0000 Subject: [PATCH 2/3] Improve `from_consensus` example The existing example at first look seemed to contradict the doc above that the function would not round trip. Update the example to show the useage for both a time and height based lock time. Replace unwrap() with ? --- primitives/src/locktime/relative.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/primitives/src/locktime/relative.rs b/primitives/src/locktime/relative.rs index f37e49354..85aeeaeaa 100644 --- a/primitives/src/locktime/relative.rs +++ b/primitives/src/locktime/relative.rs @@ -77,10 +77,19 @@ impl LockTime { /// ```rust /// # use bitcoin_primitives::relative::LockTime; /// - /// // `from_consensus` roundtrips with `to_consensus_u32` for small values. - /// let n_lock_time: u32 = 7000; - /// let lock_time = LockTime::from_consensus(n_lock_time).unwrap(); - /// assert_eq!(lock_time.to_consensus_u32(), n_lock_time); + /// // Values with bit 22 set to 0 will be interpreted as height-based lock times. + /// let height: u32 = 144; // 144 blocks, approx 24h. + /// let lock_time = LockTime::from_consensus(height)?; + /// assert!(lock_time.is_block_height()); + /// assert_eq!(lock_time.to_consensus_u32(), height); + /// + /// // Values with bit 22 set to 1 will be interpreted as time-based lock times. + /// let time: u32 = 168 | (1 << 22) ; // Bit 22 is 1 with time approx 24h. + /// let lock_time = LockTime::from_consensus(time)?; + /// assert!(lock_time.is_block_time()); + /// assert_eq!(lock_time.to_consensus_u32(), time); + /// + /// # Ok::<_, bitcoin_primitives::relative::DisabledLockTimeError>(()) /// ``` pub fn from_consensus(n: u32) -> Result { let sequence = crate::Sequence::from_consensus(n); From c16eab772375a0b8f82789a3453f7e983523fd50 Mon Sep 17 00:00:00 2001 From: "Jamil Lambert, PhD" Date: Tue, 28 Jan 2025 15:24:15 +0000 Subject: [PATCH 3/3] Add examples to `absolute::LockTime` --- primitives/src/locktime/absolute.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/primitives/src/locktime/absolute.rs b/primitives/src/locktime/absolute.rs index b48d8f9bd..5bb295c8f 100644 --- a/primitives/src/locktime/absolute.rs +++ b/primitives/src/locktime/absolute.rs @@ -91,12 +91,34 @@ impl LockTime { pub const SIZE: usize = 4; // Serialized length of a u32. /// Constructs a new `LockTime` from a prefixed hex string. + /// + /// # Examples + /// + /// ``` + /// # use bitcoin_primitives::absolute::LockTime; + /// let hex_str = "0x61cf9980"; // Unix timestamp for January 1, 2022 + /// let lock_time = LockTime::from_hex(hex_str)?; + /// assert_eq!(lock_time.to_consensus_u32(), 0x61cf9980); + /// + /// # Ok::<_, units::parse::PrefixedHexError>(()) + /// ``` pub fn from_hex(s: &str) -> Result { let lock_time = parse::hex_u32_prefixed(s)?; Ok(Self::from_consensus(lock_time)) } /// Constructs a new `LockTime` from an unprefixed hex string. + /// + /// # Examples + /// + /// ``` + /// # use bitcoin_primitives::absolute::LockTime; + /// let hex_str = "61cf9980"; // Unix timestamp for January 1, 2022 + /// let lock_time = LockTime::from_unprefixed_hex(hex_str)?; + /// assert_eq!(lock_time.to_consensus_u32(), 0x61cf9980); + /// + /// # Ok::<_, units::parse::UnprefixedHexError>(()) + /// ``` pub fn from_unprefixed_hex(s: &str) -> Result { let lock_time = parse::hex_u32_unprefixed(s)?; Ok(Self::from_consensus(lock_time))