pub enum LockTime {
Blocks(Height),
Seconds(MedianTimePast),
}Expand description
An absolute lock time value, representing either a block height or a UNIX timestamp (seconds since epoch).
Used for transaction lock time (nLockTime in Bitcoin Core and Transaction::lock_time
in rust-bitcoin) and also for the argument to opcode OP_CHECKLOCKTIMEVERIFY.
§Note on ordering
Locktimes may be height- or time-based, and these metrics are incommensurate; there is no total
ordering on locktimes. In order to compare locktimes, instead of using < or > we provide the
LockTime::is_satisfied_by API.
For transaction, which has a locktime field, we implement a total ordering to make it easy to store transactions in sorted data structures, and use the locktime’s 32-bit integer consensus encoding to order it.
§Relevant BIPs
§Examples
use bitcoin_units::absolute::{self, LockTime as L};
// To compare absolute lock times there are various `is_satisfied_*` methods, you may also use:
let _is_satisfied = match (n, lock_time) {
(L::Blocks(n), L::Blocks(lock_time)) => n <= lock_time,
(L::Seconds(n), L::Seconds(lock_time)) => n <= lock_time,
_ => panic!("handle invalid comparison error"),
};Variants§
Blocks(Height)
A block height lock time value.
§Examples
use bitcoin_units::absolute;
let block: u32 = 741521;
let n = absolute::LockTime::from_height(block).expect("valid height");
assert!(n.is_block_height());
assert_eq!(n.to_consensus_u32(), block);Seconds(MedianTimePast)
A UNIX timestamp lock time value.
§Examples
use bitcoin_units::absolute;
let seconds: u32 = 1653195600; // May 22nd, 5am UTC.
let n = absolute::LockTime::from_mtp(seconds).expect("valid time");
assert!(n.is_block_time());
assert_eq!(n.to_consensus_u32(), seconds);Implementations§
Source§impl LockTime
impl LockTime
Sourcepub const ZERO: Self
pub const ZERO: Self
If transaction lock time is set to zero it is ignored, in other words a transaction with nLocktime==0 is able to be included immediately in any block.
Sourcepub const SIZE: usize = 4
pub const SIZE: usize = 4
The number of bytes that the locktime contributes to the size of a transaction.
Sourcepub fn from_hex(s: &str) -> Result<Self, PrefixedHexError>
pub fn from_hex(s: &str) -> Result<Self, PrefixedHexError>
Constructs a new LockTime from a prefixed hex string.
§Errors
If the input string is not a valid hex representation of a locktime or it does not include
the 0x prefix.
§Examples
let hex_str = "0x61cf9980"; // Unix timestamp for January 1, 2022
let lock_time = absolute::LockTime::from_hex(hex_str)?;
assert_eq!(lock_time.to_consensus_u32(), 0x61cf9980);
Sourcepub fn from_unprefixed_hex(s: &str) -> Result<Self, UnprefixedHexError>
pub fn from_unprefixed_hex(s: &str) -> Result<Self, UnprefixedHexError>
Constructs a new LockTime from an unprefixed hex string.
§Errors
If the input string is not a valid hex representation of a locktime or if it includes the
0x prefix.
§Examples
let hex_str = "61cf9980"; // Unix timestamp for January 1, 2022
let lock_time = absolute::LockTime::from_unprefixed_hex(hex_str)?;
assert_eq!(lock_time.to_consensus_u32(), 0x61cf9980);
Sourcepub fn from_consensus(n: u32) -> Self
pub fn from_consensus(n: u32) -> Self
Constructs a new LockTime from an nLockTime value or the argument to OP_CHECKLOCKTIMEVERIFY.
§Examples
// `from_consensus` roundtrips as expected with `to_consensus_u32`.
let n_lock_time: u32 = 741521;
let lock_time = absolute::LockTime::from_consensus(n_lock_time);
assert_eq!(lock_time.to_consensus_u32(), n_lock_time);Sourcepub fn from_height(n: u32) -> Result<Self, ConversionError>
pub fn from_height(n: u32) -> Result<Self, ConversionError>
Constructs a new LockTime from n, expecting n to be a valid block height.
§Note
If the current block height is h and the locktime is set to h,
the transaction can be included in block h+1 or later.
It is possible to broadcast the transaction at block height h.
See LOCK_TIME_THRESHOLD for definition of a valid height value.
§Errors
If n does not represent a block height within the valid range for a locktime:
[0, 499_999_999].
§Examples
assert!(absolute::LockTime::from_height(741521).is_ok());
assert!(absolute::LockTime::from_height(1653195600).is_err());Sourcepub fn from_mtp(n: u32) -> Result<Self, ConversionError>
pub fn from_mtp(n: u32) -> Result<Self, ConversionError>
Constructs a new LockTime from n, expecting n to be a median-time-past (MTP)
which is in range for a locktime.
§Note
If the locktime is set to an MTP T, the transaction can be included in a block only if
the MTP of last recent 11 blocks is greater than T.
It is possible to broadcast the transaction once the MTP is greater than T. See BIP-0113.
BIP-0113 Median time-past as endpoint for lock-time calculations
See LOCK_TIME_THRESHOLD for definition of a valid time value.
§Errors
If n is not in the allowable range of MTPs in a locktime: [500_000_000, 2^32 - 1].
§Examples
assert!(absolute::LockTime::from_mtp(1653195600).is_ok());
assert!(absolute::LockTime::from_mtp(741521).is_err());Sourcepub const fn is_same_unit(self, other: Self) -> bool
pub const fn is_same_unit(self, other: Self) -> bool
Returns true if both lock times use the same unit i.e., both height based or both time based.
Sourcepub const fn is_block_height(self) -> bool
pub const fn is_block_height(self) -> bool
Returns true if this lock time value is a block height.
Sourcepub const fn is_block_time(self) -> bool
pub const fn is_block_time(self) -> bool
Returns true if this lock time value is a block time (UNIX timestamp).
Sourcepub fn is_satisfied_by(self, height: Height, mtp: MedianTimePast) -> bool
pub fn is_satisfied_by(self, height: Height, mtp: MedianTimePast) -> bool
Returns true if this timelock constraint is satisfied by the respective height/time.
If self is a blockheight based lock then it is checked against height and if self is a
blocktime based lock it is checked against time.
A ‘timelock constraint’ refers to the n from n OP_CHECKLOCKTIMEVERIFY, this constraint
is satisfied if a transaction with nLockTime set to height/time is valid.
If height and mtp represent the current chain tip then a transaction with this
locktime can be broadcast for inclusion in the next block.
If you do not have, or do not wish to calculate, both parameters consider using:
§Examples
// Can be implemented if block chain data is available.
fn get_height() -> absolute::Height { todo!("return the current block height") }
fn get_time() -> absolute::MedianTimePast { todo!("return the current block MTP") }
let n = absolute::LockTime::from_consensus(741521); // `n OP_CHECKLOCKTIMEVERIFY`.
if n.is_satisfied_by(get_height(), get_time()) {
// Can create and mine a transaction that satisfies the OP_CLTV timelock constraint.
}Sourcepub fn is_satisfied_by_height(
self,
height: Height,
) -> Result<bool, IncompatibleHeightError>
pub fn is_satisfied_by_height( self, height: Height, ) -> Result<bool, IncompatibleHeightError>
Returns true if a transaction with this locktime can be spent in the next block.
If height is the current block height of the chain then a transaction with this locktime
can be broadcast for inclusion in the next block.
§Errors
Returns an error if this lock is not lock-by-height.
Sourcepub fn is_satisfied_by_time(
self,
mtp: MedianTimePast,
) -> Result<bool, IncompatibleTimeError>
pub fn is_satisfied_by_time( self, mtp: MedianTimePast, ) -> Result<bool, IncompatibleTimeError>
Returns true if a transaction with this locktime can be included in the next block.
§Errors
Returns an error if this lock is not lock-by-time.
Sourcepub fn is_implied_by(self, other: Self) -> bool
pub fn is_implied_by(self, other: Self) -> bool
Returns true if satisfaction of other lock time implies satisfaction of this
absolute::LockTime.
A lock time can only be satisfied by n blocks being mined or n seconds passing. If you have two lock times (same unit) then the larger lock time being satisfied implies (in a mathematical sense) the smaller one being satisfied.
This function serves multiple purposes:
-
When evaluating
OP_CHECKLOCKTIMEVERIFYthe argument must be less than or equal to the transactions nLockTime. If using this function to validate a scriptselfis the argument toCLTVandotheris the transaction nLockTime. -
If you wish to check a lock time against various other locks e.g., filtering out locks which cannot be satisfied. Can also be used to remove the smaller value of two
OP_CHECKLOCKTIMEVERIFYoperations within one branch of the script.
§Examples
let lock_time = absolute::LockTime::from_consensus(741521);
let check = absolute::LockTime::from_consensus(741521 + 1);
assert!(lock_time.is_implied_by(check));Sourcepub fn to_consensus_u32(self) -> u32
pub fn to_consensus_u32(self) -> u32
Returns the inner u32 value. This is the value used when creating this LockTime
i.e., n OP_CHECKLOCKTIMEVERIFY or nLockTime.
§Warning
Do not compare values return by this method. The whole point of the LockTime type is to
assist in doing correct comparisons. Either use is_satisfied_by, is_satisfied_by_lock,
or use the pattern below:
§Examples
use bitcoin_units::absolute::{self, LockTime as L};
let _is_satisfied = match (n, lock_time) {
(L::Blocks(n), L::Blocks(lock_time)) => n <= lock_time,
(L::Seconds(n), L::Seconds(lock_time)) => n <= lock_time,
_ => panic!("invalid comparison"),
};
// Or, if you have Rust 1.53 or greater
// let is_satisfied = n.partial_cmp(&lock_time).expect("invalid comparison").is_le();Trait Implementations§
Source§impl<'a> Arbitrary<'a> for LockTime
Available on crate feature arbitrary only.
impl<'a> Arbitrary<'a> for LockTime
arbitrary only.Source§fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self>
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self>
Self from the given unstructured data. Read moreSource§fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self, Error>
fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self, Error>
Self from the entirety of the given
unstructured data. Read moreSource§fn size_hint(depth: usize) -> (usize, Option<usize>)
fn size_hint(depth: usize) -> (usize, Option<usize>)
Unstructured this type
needs to construct itself. Read moreSource§fn try_size_hint(
depth: usize,
) -> Result<(usize, Option<usize>), MaxRecursionReached>
fn try_size_hint( depth: usize, ) -> Result<(usize, Option<usize>), MaxRecursionReached>
Unstructured this type
needs to construct itself. Read moreSource§impl<'de> Deserialize<'de> for LockTime
Available on crate feature serde only.
impl<'de> Deserialize<'de> for LockTime
serde only.