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