units: deprecate relative::MtpInterval::to_consensus_u32

This method is weird. It's basically just used internally to implement
the locktime methods in `primitives` and `bitcoin`. It has no symmetric
from_consensus_u32.

Conversely the constructors from 512-second intervals have no symmetric
to_* method -- the inverse of these functions is called `value`, which
is a meaningless and undiscoverable name.
This commit is contained in:
Andrew Poelstra 2025-05-01 18:12:07 +00:00
parent 1a6b8b4c7a
commit d3619cc1bc
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
3 changed files with 27 additions and 9 deletions

View File

@ -129,7 +129,8 @@ impl LockTime {
pub fn to_consensus_u32(self) -> u32 {
match self {
LockTime::Blocks(ref h) => h.to_consensus_u32(),
LockTime::Time(ref t) => t.to_consensus_u32(),
LockTime::Time(ref t) =>
Sequence::LOCK_TYPE_MASK | u32::from(t.to_512_second_intervals()),
}
}
@ -289,8 +290,8 @@ impl LockTime {
use LockTime as L;
match (self, other) {
(L::Blocks(this), L::Blocks(other)) => this.value() <= other.value(),
(L::Time(this), L::Time(other)) => this.value() <= other.value(),
(L::Blocks(this), L::Blocks(other)) => this <= other,
(L::Time(this), L::Time(other)) => this <= other,
_ => false, // Not the same units.
}
}
@ -371,7 +372,7 @@ impl LockTime {
use LockTime as L;
match self {
L::Time(ref t) => Ok(t.value() <= time.value()),
L::Time(ref t) => Ok(t.to_512_second_intervals() <= time.to_512_second_intervals()),
L::Blocks(height) => Err(IncompatibleTimeError { time, height }),
}
}

View File

@ -70,7 +70,7 @@ impl Sequence {
/// BIP-68 relative lock time disable flag mask.
const LOCK_TIME_DISABLE_FLAG_MASK: u32 = 0x8000_0000;
/// BIP-68 relative lock time type flag mask.
const LOCK_TYPE_MASK: u32 = 0x0040_0000;
pub(super) const LOCK_TYPE_MASK: u32 = 0x0040_0000;
/// Returns `true` if the sequence number enables absolute lock-time ([`Transaction::lock_time`]).
#[inline]
@ -263,8 +263,14 @@ impl<'a> Arbitrary<'a> for Sequence {
3 => Ok(Sequence::ENABLE_LOCKTIME_AND_RBF),
4 => Ok(Sequence::from_consensus(relative::Height::MIN.to_consensus_u32())),
5 => Ok(Sequence::from_consensus(relative::Height::MAX.to_consensus_u32())),
6 => Ok(Sequence::from_consensus(relative::MtpInterval::MIN.to_consensus_u32())),
7 => Ok(Sequence::from_consensus(relative::MtpInterval::MAX.to_consensus_u32())),
6 => Ok(Sequence::from_consensus(
Sequence::LOCK_TYPE_MASK
| u32::from(relative::MtpInterval::MIN.to_512_second_intervals()),
)),
7 => Ok(Sequence::from_consensus(
Sequence::LOCK_TYPE_MASK
| u32::from(relative::MtpInterval::MAX.to_512_second_intervals()),
)),
_ => Ok(Sequence(u.arbitrary()?)),
}
}

View File

@ -101,6 +101,11 @@ impl MtpInterval {
#[inline]
pub const fn from_512_second_intervals(intervals: u16) -> Self { MtpInterval(intervals) }
/// Express the [`MtpInterval`] as an integer number of 512-second intervals.
#[inline]
#[must_use]
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
/// truncating division.
///
@ -138,11 +143,16 @@ impl MtpInterval {
/// Returns the inner `u16` value.
#[inline]
#[must_use]
#[deprecated(since = "TBD", note = "use `to_512_second_intervals` instead")]
#[doc(hidden)]
pub const fn value(self) -> u16 { self.0 }
/// Returns the `u32` value used to encode this locktime in an nSequence field or
/// argument to `OP_CHECKSEQUENCEVERIFY`.
#[inline]
#[deprecated(
since = "TBD",
note = "use `LockTime::from` followed by `to_consensus_u32` instead"
)]
pub const fn to_consensus_u32(self) -> u32 {
(1u32 << 22) | self.0 as u32 // cast safety: u32 is wider than u16 on all architectures
}
@ -159,7 +169,7 @@ impl MtpInterval {
/// - `true` if the relativetime lock has expired by the tips MTP
/// - `false` if the lock has not yet expired by the tips MTP
pub fn is_satisfied_by(self, chain_tip: MtpAndHeight, utxo_mined_at: MtpAndHeight) -> bool {
match u32::from(self.value()).checked_mul(512) {
match u32::from(self.to_512_second_intervals()).checked_mul(512) {
Some(seconds) => match seconds.checked_add(utxo_mined_at.to_mtp().to_u32()) {
Some(required_seconds) => chain_tip.to_mtp().to_u32() >= required_seconds,
None => false,
@ -245,6 +255,7 @@ mod tests {
const MAXIMUM_ENCODABLE_SECONDS: u32 = u16::MAX as u32 * 512;
#[test]
#[allow(deprecated_in_future)]
fn sanity_check() {
assert_eq!(Height::MAX.to_consensus_u32(), u32::from(u16::MAX));
assert_eq!(MtpInterval::from_512_second_intervals(100).value(), 100u16);