Merge rust-bitcoin/rust-bitcoin#3421: Const locktime constructors

de319670ae feat: Create relative lock times at compile time (Christian Lewe)
53e1fb6b0c feat: Create absolute lock time at compile time (Christian Lewe)

Pull request description:

  I noticed that I cannot create lock times as compile-time constants. This PR tries to remedy this issue by marking lock time constructors as `const`.

  Because the `internals` crate depends on the `units` crate in a way that I don't fully understand yet, this PR updates the `units` crate only.

  If `from_consensus` is being kept non-`const` by design, to keep the API flexible to future changes, then please close this PR. In this case, I overlooked existing discussions.

ACKs for top commit:
  apoelstra:
    ACK de319670ae successfully ran local tests; good start; should backport
  tcharding:
    ACK de319670ae

Tree-SHA512: 69f9147707bcf8f91f755dd6d1be5ed08945e775ee46918e33d77a9d07ce474047a80ed1226134a3914ead51d1ddbbc657552ca934dc3c079b92ad3d50b13152
This commit is contained in:
merge-script 2024-09-30 16:29:18 +00:00
commit 95be55177e
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
2 changed files with 16 additions and 12 deletions

View File

@ -62,7 +62,7 @@ impl Height {
/// assert_eq!(height.to_consensus_u32(), h);
/// ```
#[inline]
pub fn from_consensus(n: u32) -> Result<Height, ConversionError> {
pub const fn from_consensus(n: u32) -> Result<Height, ConversionError> {
if is_block_height(n) {
Ok(Self(n))
} else {
@ -72,7 +72,7 @@ impl Height {
/// Converts this [`Height`] to its inner `u32` value.
#[inline]
pub fn to_consensus_u32(self) -> u32 { self.0 }
pub const fn to_consensus_u32(self) -> u32 { self.0 }
}
impl fmt::Display for Height {
@ -158,7 +158,7 @@ impl Time {
/// assert_eq!(time.to_consensus_u32(), t);
/// ```
#[inline]
pub fn from_consensus(n: u32) -> Result<Time, ConversionError> {
pub const fn from_consensus(n: u32) -> Result<Time, ConversionError> {
if is_block_time(n) {
Ok(Self(n))
} else {
@ -168,7 +168,7 @@ impl Time {
/// Converts this [`Time`] to its inner `u32` value.
#[inline]
pub fn to_consensus_u32(self) -> u32 { self.0 }
pub const fn to_consensus_u32(self) -> u32 { self.0 }
}
impl fmt::Display for Time {
@ -244,10 +244,10 @@ where
}
/// Returns true if `n` is a block height i.e., less than 500,000,000.
pub fn is_block_height(n: u32) -> bool { n < LOCK_TIME_THRESHOLD }
pub const fn is_block_height(n: u32) -> bool { n < LOCK_TIME_THRESHOLD }
/// Returns true if `n` is a UNIX timestamp i.e., greater than or equal to 500,000,000.
pub fn is_block_time(n: u32) -> bool { n >= LOCK_TIME_THRESHOLD }
pub const fn is_block_time(n: u32) -> bool { n >= LOCK_TIME_THRESHOLD }
/// An error that occurs when converting a `u32` to a lock time variant.
#[derive(Debug, Clone, PartialEq, Eq)]
@ -261,10 +261,10 @@ pub struct ConversionError {
impl ConversionError {
/// Constructs a `ConversionError` from an invalid `n` when expecting a height value.
fn invalid_height(n: u32) -> Self { Self { unit: LockTimeUnit::Blocks, input: n } }
const fn invalid_height(n: u32) -> Self { Self { unit: LockTimeUnit::Blocks, input: n } }
/// Constructs a `ConversionError` from an invalid `n` when expecting a time value.
fn invalid_time(n: u32) -> Self { Self { unit: LockTimeUnit::Seconds, input: n } }
const fn invalid_time(n: u32) -> Self { Self { unit: LockTimeUnit::Seconds, input: n } }
}
impl fmt::Display for ConversionError {

View File

@ -28,12 +28,14 @@ impl Height {
/// Returns the inner `u16` value.
#[inline]
pub fn value(self) -> u16 { self.0 }
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]
pub fn to_consensus_u32(&self) -> u32 { self.0.into() }
pub const fn to_consensus_u32(&self) -> u32 {
self.0 as u32 // cast safety: u32 is wider than u16 on all architectures
}
}
impl From<u16> for Height {
@ -106,12 +108,14 @@ impl Time {
/// Returns the inner `u16` value.
#[inline]
pub fn value(self) -> u16 { self.0 }
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]
pub fn to_consensus_u32(&self) -> u32 { (1u32 << 22) | u32::from(self.0) }
pub const fn to_consensus_u32(&self) -> u32 {
(1u32 << 22) | self.0 as u32 // cast safety: u32 is wider than u16 on all architectures
}
}
crate::impl_parse_str_from_int_infallible!(Time, u16, from_512_second_intervals);