diff --git a/bitcoin/src/blockdata/locktime/absolute.rs b/bitcoin/src/blockdata/locktime/absolute.rs index 1c4b58f0..70d920f9 100644 --- a/bitcoin/src/blockdata/locktime/absolute.rs +++ b/bitcoin/src/blockdata/locktime/absolute.rs @@ -33,11 +33,12 @@ pub use units::locktime::absolute::{ /// /// ### Note on ordering /// -/// Because locktimes may be height- or time-based, and these metrics are incommensurate, there -/// is no total ordering on locktimes. We therefore have implemented [`PartialOrd`] but not [`Ord`]. +/// Locktimes may be height- or time-based, and these metrics are incommensurate; there is no total +/// ordering on locktimes. We therefore have implemented [`PartialOrd`] but not [`Ord`]. /// For [`crate::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. +/// consensus encoding to order it. We also implement [`ordered::ArbitraryOrd`] if the "ordered" +/// feature is enabled. /// /// ### Relevant BIPs /// diff --git a/bitcoin/src/blockdata/locktime/relative.rs b/bitcoin/src/blockdata/locktime/relative.rs index f574f7fb..04fe4bda 100644 --- a/bitcoin/src/blockdata/locktime/relative.rs +++ b/bitcoin/src/blockdata/locktime/relative.rs @@ -6,6 +6,8 @@ //! whether bit 22 of the `u32` consensus value is set. //! +#[cfg(feature = "ordered")] +use core::cmp::Ordering; use core::{cmp, convert, fmt}; #[cfg(all(test, mutate))] @@ -26,8 +28,9 @@ pub use units::locktime::relative::{Height, Time, TimeOverflowError}; /// /// ### Note on ordering /// -/// Because locktimes may be height- or time-based, and these metrics are incommensurate, there -/// is no total ordering on locktimes. We therefore have implemented [`PartialOrd`] but not [`Ord`]. +/// Locktimes may be height- or time-based, and these metrics are incommensurate; there is no total +/// ordering on locktimes. We therefore have implemented [`PartialOrd`] but not [`Ord`]. We also +/// implement [`ordered::ArbitraryOrd`] if the "ordered" feature is enabled. /// /// ### Relevant BIPs /// @@ -338,6 +341,20 @@ impl fmt::Display for LockTime { } } +#[cfg(feature = "ordered")] +impl ordered::ArbitraryOrd for LockTime { + fn arbitrary_cmp(&self, other: &Self) -> Ordering { + use LockTime::*; + + match (self, other) { + (Blocks(_), Time(_)) => Ordering::Less, + (Time(_), Blocks(_)) => Ordering::Greater, + (Blocks(this), Blocks(that)) => this.cmp(that), + (Time(this), Time(that)) => this.cmp(that), + } + } +} + impl convert::TryFrom for LockTime { type Error = DisabledLockTimeError; fn try_from(seq: Sequence) -> Result {