Skip to main content

bitcoin_units/
sequence.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! Bitcoin transaction input sequence number.
4//!
5//! The sequence field is used for:
6//! - Indicating whether absolute lock-time (specified in `lock_time` field of `Transaction`) is enabled.
7//! - Indicating and encoding [BIP-0068] relative lock-times.
8//! - Indicating whether a transaction opts-in to [BIP-0125] replace-by-fee.
9//!
10//! Note that transactions spending an output with `OP_CHECKLOCKTIMEVERIFY` MUST NOT use
11//! [`Sequence::MAX`] for the corresponding input. [BIP-0065]
12//!
13//! [BIP-0065]: <https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki>
14//! [BIP-0068]: <https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki>
15//! [BIP-0125]: <https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki>
16
17use core::fmt;
18
19#[cfg(feature = "arbitrary")]
20use arbitrary::{Arbitrary, Unstructured};
21#[cfg(feature = "serde")]
22use serde::{Deserialize, Serialize};
23
24use crate::locktime::relative::error::TimeOverflowError;
25use crate::locktime::relative::{self, NumberOf512Seconds};
26use crate::parse_int::{self, PrefixedHexError, UnprefixedHexError};
27
28#[rustfmt::skip]                // Keep public re-exports separate.
29#[cfg(feature = "encoding")]
30#[doc(no_inline)]
31pub use self::error::SequenceDecoderError;
32
33/// Bitcoin transaction input sequence number.
34#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
35#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
36pub struct Sequence(u32);
37
38impl Sequence {
39    /// The maximum allowable sequence number.
40    ///
41    /// The sequence number that disables replace-by-fee, absolute lock time and relative lock time.
42    pub const MAX: Self = Self(0xFFFF_FFFF);
43
44    /// Zero value sequence.
45    ///
46    /// This sequence number enables replace-by-fee and absolute lock time.
47    pub const ZERO: Self = Self(0);
48
49    /// The sequence number that disables replace-by-fee, absolute lock time and relative lock time.
50    pub const FINAL: Self = Self::MAX;
51
52    /// The sequence number that enables absolute lock time but disables replace-by-fee
53    /// and relative lock time.
54    pub const ENABLE_LOCKTIME_NO_RBF: Self = Self::MIN_NO_RBF;
55
56    /// The maximum sequence number that enables replace-by-fee and absolute lock time but
57    /// disables relative lock time.
58    ///
59    /// This sequence number has no meaning other than to enable RBF and the absolute locktime.
60    pub const ENABLE_LOCKTIME_AND_RBF: Self = Self(0xFFFF_FFFD);
61
62    /// The number of bytes that a sequence number contributes to the size of a transaction.
63    pub const SIZE: usize = 4; // Serialized length of a u32.
64
65    /// The lowest sequence number that does not opt-in for replace-by-fee.
66    ///
67    /// A transaction is considered to have opted in to replacement of itself
68    /// if any of its inputs have a [`Sequence`] number less than this value
69    /// (Explicit Signalling [BIP-0125]).
70    ///
71    /// [BIP-0125]: <https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki>
72    const MIN_NO_RBF: Self = Self(0xFFFF_FFFE);
73
74    /// BIP-0068 relative lock time disable flag mask.
75    const LOCK_TIME_DISABLE_FLAG_MASK: u32 = 0x8000_0000;
76
77    /// BIP-0068 relative lock time type flag mask.
78    pub(super) const LOCK_TYPE_MASK: u32 = 0x0040_0000;
79
80    /// Returns `true` if the sequence number enables absolute lock-time (`Transaction::lock_time`).
81    #[inline]
82    pub fn enables_absolute_lock_time(self) -> bool { self != Self::MAX }
83
84    /// Returns `true` if the sequence number indicates that the transaction is finalized.
85    ///
86    /// Instead of this method please consider using `!enables_absolute_lock_time` because it
87    /// is equivalent and improves readability for those not steeped in Bitcoin folklore.
88    ///
89    /// # Historical note
90    ///
91    /// The term 'final' is an archaic Bitcoin term, it may have come about because the sequence
92    /// number in the original Bitcoin code was intended to be incremented in order to replace a
93    /// transaction, so once the sequence number got to `u32::MAX` it could no longer be increased,
94    /// hence it was 'final'.
95    ///
96    ///
97    /// Some other references to the term:
98    /// - `CTxIn::SEQUENCE_FINAL` in the Bitcoin Core code.
99    /// - [BIP-0112]: "BIP-0068 prevents a non-final transaction from being selected for inclusion in a
100    ///   block until the corresponding input has reached the specified age"
101    ///
102    /// [BIP-0112]: <https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki>
103    #[inline]
104    pub fn is_final(self) -> bool { !self.enables_absolute_lock_time() }
105
106    /// Returns `true` if the transaction opted-in to BIP-0125 replace-by-fee.
107    ///
108    /// Replace by fee is signaled by the sequence being less than 0xfffffffe which is checked by
109    /// this method. Note, this is the highest "non-final" value (see [`Sequence::is_final`]).
110    #[inline]
111    pub fn is_rbf(self) -> bool { self < Self::MIN_NO_RBF }
112
113    /// Returns `true` if the sequence has a relative lock-time.
114    #[inline]
115    pub fn is_relative_lock_time(self) -> bool { self.0 & Self::LOCK_TIME_DISABLE_FLAG_MASK == 0 }
116
117    /// Returns `true` if the sequence number encodes a block based relative lock-time.
118    #[inline]
119    pub fn is_height_locked(self) -> bool {
120        self.is_relative_lock_time() && (self.0 & Self::LOCK_TYPE_MASK == 0)
121    }
122
123    /// Returns `true` if the sequence number encodes a time interval based relative lock-time.
124    #[inline]
125    pub fn is_time_locked(self) -> bool {
126        self.is_relative_lock_time() && (self.0 & Self::LOCK_TYPE_MASK > 0)
127    }
128
129    /// Constructs a new [`Sequence`] from a prefixed hex string.
130    ///
131    /// # Errors
132    ///
133    /// If the input string is not a valid hex representation of a locktime or it does not include
134    /// the `0x` prefix.
135    #[inline]
136    pub fn from_hex(s: &str) -> Result<Self, PrefixedHexError> {
137        let lock_time = parse_int::hex_u32_prefixed(s)?;
138        Ok(Self::from_consensus(lock_time))
139    }
140
141    /// Constructs a new [`Sequence`] from an unprefixed hex string.
142    ///
143    /// # Errors
144    ///
145    /// If the input string is not a valid hex representation of a locktime or if it includes the
146    /// `0x` prefix.
147    #[inline]
148    pub fn from_unprefixed_hex(s: &str) -> Result<Self, UnprefixedHexError> {
149        let lock_time = parse_int::hex_u32_unprefixed(s)?;
150        Ok(Self::from_consensus(lock_time))
151    }
152
153    /// Constructs a new relative lock-time using a count of blocks.
154    #[inline]
155    pub fn from_height(height: u16) -> Self { Self(u32::from(height)) }
156
157    /// Constructs a new relative lock-time using time intervals where each interval is equivalent
158    /// to 512 seconds.
159    ///
160    /// Encoding finer granularity of time for relative lock-times is not supported in Bitcoin.
161    #[inline]
162    pub fn from_512_second_intervals(intervals: u16) -> Self {
163        Self(u32::from(intervals) | Self::LOCK_TYPE_MASK)
164    }
165
166    /// Constructs a new relative lock-time from seconds, converting the seconds into 512 second
167    /// interval with floor division.
168    ///
169    /// Will return an error if the input cannot be encoded in 16 bits.
170    ///
171    /// # Errors
172    ///
173    /// Will return an error if `seconds` cannot be encoded in 16 bits. See
174    /// [`NumberOf512Seconds::from_seconds_floor`].
175    #[inline]
176    pub fn from_seconds_floor(seconds: u32) -> Result<Self, TimeOverflowError> {
177        let intervals = NumberOf512Seconds::from_seconds_floor(seconds)?;
178        Ok(Self::from_512_second_intervals(intervals.to_512_second_intervals()))
179    }
180
181    /// Constructs a new relative lock-time from seconds, converting the seconds into 512 second
182    /// interval with ceiling division.
183    ///
184    /// Will return an error if the input cannot be encoded in 16 bits.
185    ///
186    /// # Errors
187    ///
188    /// Will return an error if `seconds` cannot be encoded in 16 bits. See
189    /// [`NumberOf512Seconds::from_seconds_ceil`].
190    #[inline]
191    pub fn from_seconds_ceil(seconds: u32) -> Result<Self, TimeOverflowError> {
192        let intervals = NumberOf512Seconds::from_seconds_ceil(seconds)?;
193        Ok(Self::from_512_second_intervals(intervals.to_512_second_intervals()))
194    }
195
196    /// Constructs a new sequence from a u32 value.
197    #[inline]
198    pub fn from_consensus(n: u32) -> Self { Self(n) }
199
200    /// Returns the inner 32-bit integer value of Sequence.
201    #[inline]
202    pub const fn to_consensus_u32(self) -> u32 { self.0 }
203
204    /// Constructs a new [`relative::LockTime`] from this [`Sequence`] number.
205    #[inline]
206    pub fn to_relative_lock_time(self) -> Option<relative::LockTime> {
207        use crate::locktime::relative::{LockTime, NumberOfBlocks};
208
209        if !self.is_relative_lock_time() {
210            return None;
211        }
212
213        let lock_value = self.low_u16();
214
215        if self.is_time_locked() {
216            Some(LockTime::from(NumberOf512Seconds::from_512_second_intervals(lock_value)))
217        } else {
218            Some(LockTime::from(NumberOfBlocks::from_count(lock_value)))
219        }
220    }
221
222    /// Returns the low 16 bits from sequence number.
223    ///
224    /// BIP-0068 only uses the low 16 bits for relative lock value.
225    #[inline]
226    const fn low_u16(self) -> u16 { self.0 as u16 }
227}
228
229crate::internal_macros::impl_fmt_traits_for_u32_wrapper!(Sequence);
230
231impl From<Sequence> for u32 {
232    #[inline]
233    fn from(sequence: Sequence) -> Self { sequence.0 }
234}
235
236impl fmt::Display for Sequence {
237    #[inline]
238    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
239}
240
241impl fmt::Debug for Sequence {
242    #[inline]
243    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
244        // 10 because its 8 digits + 2 for the '0x'
245        write!(f, "Sequence({:#010x})", self.0)
246    }
247}
248
249parse_int::impl_parse_str_from_int_infallible!(Sequence, u32, from_consensus);
250
251#[cfg(feature = "encoding")]
252impl encoding::Encode for Sequence {
253    type Encoder<'e> = SequenceEncoder<'e>;
254    #[inline]
255    fn encoder(&self) -> Self::Encoder<'_> {
256        SequenceEncoder::new(encoding::ArrayEncoder::without_length_prefix(
257            self.to_consensus_u32().to_le_bytes(),
258        ))
259    }
260}
261
262#[cfg(feature = "encoding")]
263impl encoding::Decode for Sequence {
264    type Decoder = SequenceDecoder;
265}
266
267#[cfg(feature = "encoding")]
268encoding::encoder_newtype_exact! {
269    /// The encoder for the [`Sequence`] type.
270    #[derive(Debug, Clone)]
271    pub struct SequenceEncoder<'e>(encoding::ArrayEncoder<4>);
272}
273
274#[cfg(feature = "encoding")]
275crate::decoder_newtype! {
276    /// The decoder for the [`Sequence`] type.
277    #[derive(Debug, Clone)]
278    pub struct SequenceDecoder(encoding::ArrayDecoder<4>);
279
280    /// Constructs a new [`Sequence`] decoder.
281    pub const fn new() -> Self { Self(encoding::ArrayDecoder::new()) }
282
283    fn end(result: Result<[u8; 4], encoding::UnexpectedEofError>) -> Result<Sequence, SequenceDecoderError> {
284        let value = result.map_err(SequenceDecoderError)?;
285        let n = u32::from_le_bytes(value);
286        Ok(Sequence::from_consensus(n))
287    }
288}
289
290/// Error types for input sequence numbers.
291pub mod error {
292    #[cfg(feature = "encoding")]
293    use core::convert::Infallible;
294    #[cfg(feature = "encoding")]
295    use core::fmt;
296
297    #[cfg(feature = "encoding")]
298    use internals::write_err;
299
300    /// An error consensus decoding a [`Sequence`].
301    ///
302    /// [`Sequence`]: super::Sequence
303    #[cfg(feature = "encoding")]
304    #[derive(Debug, Clone, PartialEq, Eq)]
305    pub struct SequenceDecoderError(pub(super) encoding::UnexpectedEofError);
306
307    #[cfg(feature = "encoding")]
308    impl From<Infallible> for SequenceDecoderError {
309        #[inline]
310        fn from(never: Infallible) -> Self { match never {} }
311    }
312
313    #[cfg(feature = "encoding")]
314    impl fmt::Display for SequenceDecoderError {
315        #[inline]
316        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
317            write_err!(f, "sequence decoder error"; self.0)
318        }
319    }
320
321    #[cfg(feature = "encoding")]
322    #[cfg(feature = "std")]
323    impl std::error::Error for SequenceDecoderError {
324        #[inline]
325        fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
326    }
327}
328
329#[cfg(feature = "arbitrary")]
330#[cfg(feature = "alloc")]
331impl<'a> Arbitrary<'a> for Sequence {
332    fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
333        // Equally weight the cases of meaningful sequence numbers
334        let choice = u.int_in_range(0..=8)?;
335        match choice {
336            0 => Ok(Self::MAX),
337            1 => Ok(Self::ZERO),
338            2 => Ok(Self::MIN_NO_RBF),
339            3 => Ok(Self::ENABLE_LOCKTIME_AND_RBF),
340            4 => Ok(Self::from_consensus(u32::from(relative::NumberOfBlocks::MIN.to_count()))),
341            5 => Ok(Self::from_consensus(u32::from(relative::NumberOfBlocks::MAX.to_count()))),
342            6 => Ok(Self::from_consensus(
343                Self::LOCK_TYPE_MASK
344                    | u32::from(relative::NumberOf512Seconds::MIN.to_512_second_intervals()),
345            )),
346            7 => Ok(Self::from_consensus(
347                Self::LOCK_TYPE_MASK
348                    | u32::from(relative::NumberOf512Seconds::MAX.to_512_second_intervals()),
349            )),
350            _ => Ok(Self(u.arbitrary()?)),
351        }
352    }
353}
354
355#[cfg(feature = "arbitrary")]
356#[cfg(not(feature = "alloc"))]
357impl<'a> Arbitrary<'a> for Sequence {
358    #[inline]
359    fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
360        // Equally weight the cases of meaningful sequence numbers
361        let choice = u.int_in_range(0..=4)?;
362        match choice {
363            0 => Ok(Sequence::MAX),
364            1 => Ok(Sequence::ZERO),
365            2 => Ok(Sequence::MIN_NO_RBF),
366            3 => Ok(Sequence::ENABLE_LOCKTIME_AND_RBF),
367            _ => Ok(Sequence(u.arbitrary()?)),
368        }
369    }
370}
371
372#[cfg(test)]
373mod tests {
374    #[cfg(feature = "alloc")]
375    use alloc::format;
376    #[cfg(feature = "alloc")]
377    #[cfg(feature = "encoding")]
378    use alloc::string::ToString;
379    #[cfg(feature = "encoding")]
380    #[cfg(feature = "std")]
381    use std::error::Error;
382
383    #[cfg(feature = "alloc")]
384    #[cfg(feature = "encoding")]
385    use encoding::UnexpectedEofError;
386    #[cfg(feature = "encoding")]
387    use encoding::{Decode as _, Decoder as _};
388
389    use super::*;
390
391    const MAXIMUM_ENCODABLE_SECONDS: u32 = u16::MAX as u32 * 512;
392
393    #[test]
394    fn from_seconds_floor_success() {
395        let expected = Sequence::from_hex("0x0040ffff").unwrap();
396        let actual = Sequence::from_seconds_floor(MAXIMUM_ENCODABLE_SECONDS + 511).unwrap();
397        assert_eq!(actual, expected);
398    }
399
400    #[test]
401    fn from_seconds_floor_causes_overflow_error() {
402        assert!(Sequence::from_seconds_floor(MAXIMUM_ENCODABLE_SECONDS + 512).is_err());
403    }
404
405    #[test]
406    fn from_seconds_ceil_success() {
407        let expected = Sequence::from_hex("0x0040ffff").unwrap();
408        let actual = Sequence::from_seconds_ceil(MAXIMUM_ENCODABLE_SECONDS - 511).unwrap();
409        assert_eq!(actual, expected);
410    }
411
412    #[test]
413    fn from_seconds_ceil_causes_overflow_error() {
414        assert!(Sequence::from_seconds_ceil(MAXIMUM_ENCODABLE_SECONDS + 1).is_err());
415    }
416
417    #[test]
418    fn sequence_number() {
419        let seq_final = Sequence::from_consensus(0xFFFF_FFFF);
420        let seq_non_rbf = Sequence::from_consensus(0xFFFF_FFFE);
421        let block_time_lock = Sequence::from_consensus(0xFFFF);
422        let unit_time_lock = Sequence::from_consensus(0x40_FFFF);
423        let lock_time_disabled = Sequence::from_consensus(0x8000_0000);
424
425        assert!(seq_final.is_final());
426        assert!(!seq_final.is_rbf());
427        assert!(!seq_final.is_relative_lock_time());
428        assert!(!seq_non_rbf.is_rbf());
429        assert!(block_time_lock.is_relative_lock_time());
430        assert!(block_time_lock.is_height_locked());
431        assert!(block_time_lock.is_rbf());
432        assert!(unit_time_lock.is_relative_lock_time());
433        assert!(unit_time_lock.is_time_locked());
434        assert!(unit_time_lock.is_rbf());
435        assert!(!lock_time_disabled.is_relative_lock_time());
436    }
437
438    #[test]
439    fn sequence_from_hex_lower() {
440        let sequence = Sequence::from_hex("0xffffffff").unwrap();
441        assert_eq!(sequence, Sequence::MAX);
442    }
443
444    #[test]
445    fn sequence_from_hex_upper() {
446        let sequence = Sequence::from_hex("0XFFFFFFFF").unwrap();
447        assert_eq!(sequence, Sequence::MAX);
448    }
449
450    #[test]
451    fn sequence_from_unprefixed_hex_lower() {
452        let sequence = Sequence::from_unprefixed_hex("ffffffff").unwrap();
453        assert_eq!(sequence, Sequence::MAX);
454    }
455
456    #[test]
457    fn sequence_from_unprefixed_hex_upper() {
458        let sequence = Sequence::from_unprefixed_hex("FFFFFFFF").unwrap();
459        assert_eq!(sequence, Sequence::MAX);
460    }
461
462    #[test]
463    fn sequence_from_str_hex_invalid_hex_should_err() {
464        let hex = "0xzb93";
465        let result = Sequence::from_hex(hex);
466        assert!(result.is_err());
467    }
468
469    #[test]
470    fn sequence_properties() {
471        let seq_max = Sequence(0xFFFF_FFFF);
472        let seq_no_rbf = Sequence(0xFFFF_FFFE);
473        let seq_rbf = Sequence(0xFFFF_FFFD);
474
475        assert!(seq_max.is_final());
476        assert!(!seq_no_rbf.is_final());
477
478        assert!(seq_no_rbf.enables_absolute_lock_time());
479        assert!(!seq_max.enables_absolute_lock_time());
480
481        assert!(seq_rbf.is_rbf());
482        assert!(!seq_no_rbf.is_rbf());
483
484        let seq_relative = Sequence(0x7FFF_FFFF);
485        assert!(seq_relative.is_relative_lock_time());
486        assert!(!seq_max.is_relative_lock_time());
487
488        let seq_height_locked = Sequence(0x0039_9999);
489        let seq_time_locked = Sequence(0x0040_0000);
490        assert!(seq_height_locked.is_height_locked());
491        assert!(seq_time_locked.is_time_locked());
492        assert!(!seq_time_locked.is_height_locked());
493        assert!(!seq_height_locked.is_time_locked());
494    }
495
496    #[test]
497    #[cfg(feature = "alloc")]
498    fn sequence_formatting() {
499        let sequence = Sequence(0x7FFF_FFFF);
500        assert_eq!(format!("{:x}", sequence), "7fffffff");
501        assert_eq!(format!("{:X}", sequence), "7FFFFFFF");
502
503        // Test From<Sequence> for u32
504        let sequence_u32: u32 = sequence.into();
505        assert_eq!(sequence_u32, 0x7FFF_FFFF);
506    }
507
508    #[test]
509    #[cfg(feature = "alloc")]
510    fn sequence_display() {
511        use alloc::string::ToString;
512
513        let sequence = Sequence(0x7FFF_FFFF);
514        let want: u32 = 0x7FFF_FFFF;
515        assert_eq!(format!("{}", sequence), want.to_string());
516    }
517
518    #[test]
519    #[cfg(feature = "alloc")]
520    fn sequence_unprefixed_hex_roundtrip() {
521        let sequence = Sequence(0x7FFF_FFFF);
522
523        let hex_str = format!("{:x}", sequence);
524        assert_eq!(hex_str, "7fffffff");
525
526        let roundtrip = Sequence::from_unprefixed_hex(&hex_str).unwrap();
527        assert_eq!(sequence, roundtrip);
528    }
529
530    #[test]
531    fn sequence_from_height() {
532        // Check near the boundaries
533        assert_eq!(Sequence::from_height(0), Sequence(0));
534        assert_eq!(Sequence::from_height(1), Sequence(1));
535        assert_eq!(Sequence::from_height(0x7FFF), Sequence(0x7FFF));
536        assert_eq!(Sequence::from_height(0xFFFF), Sequence(0xFFFF));
537
538        // Check steps throughout the whole range
539        let step = 512;
540        for v in (0..=u16::MAX).step_by(step) {
541            assert_eq!(Sequence::from_height(v), Sequence(v.into()));
542        }
543    }
544
545    #[test]
546    #[cfg(feature = "alloc")]
547    #[cfg(feature = "encoding")]
548    fn sequence_decoding_error() {
549        let bytes = [0xff, 0xff, 0xff]; // 3 bytes is an EOF error
550
551        let mut decoder = SequenceDecoder::default();
552        assert!(decoder.push_bytes(&mut bytes.as_slice()).unwrap().needs_more());
553
554        let error = decoder.end().unwrap_err();
555        assert!(matches!(error, SequenceDecoderError(UnexpectedEofError { .. })));
556    }
557
558    #[test]
559    #[cfg(feature = "alloc")]
560    fn decoder_error_display_is_non_empty() {
561        #[cfg(feature = "encoding")]
562        {
563            // SequenceDecoderError
564            let mut decoder = Sequence::decoder();
565            let _ = decoder.push_bytes(&mut [0u8; 3].as_slice());
566            let e = decoder.end().unwrap_err();
567            assert!(!e.to_string().is_empty());
568            #[cfg(feature = "std")]
569            assert!(e.source().is_some());
570        }
571    }
572}