Add absolute::LockTime::is_implied_by method

When filtering it is necessary to check two lock times against each
other, we currently provide a patter for doing so in the docs but we can
do better.

It was observed that satisfaction of a lock time 'implies' satisfaction
of another lock time if the lock times are the same unit and one locks
value is less than the others - this is exactly the code pattern we
suggest for filtering.

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`).
This commit is contained in:
Tobin C. Harding 2022-09-12 08:33:45 +10:00
parent 98cbdb5a5c
commit d5492b8a25
1 changed files with 33 additions and 1 deletions

View File

@ -20,6 +20,9 @@ use crate::io::{self, Read, Write};
use crate::prelude::*; use crate::prelude::*;
use crate::parse::{self, impl_parse_str_through_int}; 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]). /// 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 /// `LockTime` values _below_ the threshold are interpreted as block heights, values _above_ (or
@ -305,13 +308,42 @@ 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.
///
/// # 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` /// Returns the inner `u32` value. This is the value used when creating this `LockTime`
/// i.e., `n OP_CHECKLOCKTIMEVERIFY` or nLockTime. /// i.e., `n OP_CHECKLOCKTIMEVERIFY` or nLockTime.
/// ///
/// # Warning /// # Warning
/// ///
/// Do not compare values return by this method. The whole point of the `LockTime` type is to /// 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 /// # Examples
/// ///