Merge rust-bitcoin/rust-bitcoin#1258: Add API method `absolute::LockTime::is_satisfied_by_lock`
8aa94bd0b2
Improve docs on is_implied_by (Tobin C. Harding)b8721bf244
Add method relative::LockTime::is_implied_by (Tobin C. Harding)d5492b8a25
Add absolute::LockTime::is_implied_by method (Tobin C. Harding)98cbdb5a5c
Increment lock value (Tobin C. Harding) Pull request description: Patch 1 is a docs improvement. Patch 2 commit log: When implementing the absolute lock time API we decided on _not_ supporting checking lock satisfaction with another lock, instead we provided a pattern in the docs for doing so. Fast forward a months and I, the primary author, then forgot to use the correct pattern when using the API in `rust-miniscript` - this is a sure sign that the API is too hard to use. In this time we worked on the relative lock API and came up with a `is_satisfied_by_lock` method - this is identical to the required use case in the absolute lock time module. Add a method on `absolute::LockTime` for checking a lock against another lock, add rustdoc comment explaining the methods function in filtering prospective lock time values (how we use it in `rust-miniscript`). ACKs for top commit: Kixunil: ACK8aa94bd0b2
apoelstra: ACK8aa94bd0b2
Tree-SHA512: 5c7efa1727a846248783c9e6044bf8b0a7550d298ca1b5d3274ef325cf82efa33392ad14ef7e3e9aa91423ba56e8a3e7f4a38a966be38f673dccefd46465ad51
This commit is contained in:
commit
a0899eb8e4
|
@ -20,6 +20,9 @@ use crate::io::{self, Read, Write};
|
|||
use crate::prelude::*;
|
||||
use crate::parse::{self, impl_parse_str_through_int};
|
||||
|
||||
#[cfg(docsrs)]
|
||||
use crate::absolute;
|
||||
|
||||
/// The Threshold for deciding whether a lock time value is a height or a time (see [Bitcoin Core]).
|
||||
///
|
||||
/// `LockTime` values _below_ the threshold are interpreted as block heights, values _above_ (or
|
||||
|
@ -305,20 +308,50 @@ impl LockTime {
|
|||
}
|
||||
}
|
||||
|
||||
/// 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 is useful 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_CHECKLOCKTIMEVERIFY` operations within one branch of the script.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// # use bitcoin::absolute::{LockTime, LockTime::*};
|
||||
/// let lock_time = LockTime::from_consensus(100);
|
||||
/// let check = LockTime::from_consensus(100 + 1);
|
||||
/// assert!(lock_time.is_implied_by(check));
|
||||
/// ```
|
||||
pub fn is_implied_by(&self, other: LockTime) -> bool {
|
||||
use LockTime::*;
|
||||
|
||||
match (*self, other) {
|
||||
(Blocks(this), Blocks(other)) => this <= other,
|
||||
(Seconds(this), Seconds(other)) => this <= other,
|
||||
_ => false, // Not the same units.
|
||||
}
|
||||
}
|
||||
|
||||
/// 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` or use the pattern below:
|
||||
/// assist in doing correct comparisons. Either use `is_satisfied_by`, `is_satisfied_by_lock`,
|
||||
/// or use the pattern below:
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// # use bitcoin::absolute::{LockTime, LockTime::*};
|
||||
/// # let n = LockTime::from_consensus(100); // n OP_CHECKLOCKTIMEVERIFY
|
||||
/// # let lock_time = LockTime::from_consensus(100); // nLockTime
|
||||
/// # let lock_time = LockTime::from_consensus(100 + 1); // nLockTime
|
||||
///
|
||||
/// let is_satisfied = match (n, lock_time) {
|
||||
/// (Blocks(n), Blocks(lock_time)) => n <= lock_time,
|
||||
|
|
|
@ -62,11 +62,19 @@ impl LockTime {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns true if this [`relative::LockTime`] is satisfied by `other` lock.
|
||||
/// Returns true if satisfaction of `other` lock time implies satisfaction of this
|
||||
/// [`relative::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 is useful when checking sequence values against a lock, first one checks the
|
||||
/// sequence represents a relative lock time by converting to `LockTime` then use this function
|
||||
/// to see if [`LockTime`] is satisfied by the newly created lock.
|
||||
/// to see if satisfaction of the newly created lock time would imply satisfaction of `self`.
|
||||
///
|
||||
/// Can also be used to remove the smaller value of two `OP_CHECKSEQUENCEVERIFY` operations
|
||||
/// within one branch of the script.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -80,16 +88,16 @@ impl LockTime {
|
|||
///
|
||||
/// let satisfied = match test_sequence.to_relative_lock_time() {
|
||||
/// None => false, // Handle non-lock-time case.
|
||||
/// Some(test_lock) => lock.is_satisfied_by_lock(test_lock),
|
||||
/// Some(test_lock) => lock.is_implied_by(test_lock),
|
||||
/// };
|
||||
/// assert!(satisfied);
|
||||
/// ```
|
||||
pub fn is_satisfied_by_lock(&self, other: LockTime) -> bool {
|
||||
pub fn is_implied_by(&self, other: LockTime) -> bool {
|
||||
use LockTime::*;
|
||||
|
||||
match (*self, other) {
|
||||
(Blocks(n), Blocks(m)) => n.value() <= m.value(),
|
||||
(Time(n), Time(m)) => n.value() <= m.value(),
|
||||
(Blocks(this), Blocks(other)) => this.value() <= other.value(),
|
||||
(Time(this), Time(other)) => this.value() <= other.value(),
|
||||
_ => false, // Not the same units.
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue