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