spark_rust/wallet/utils/
sequence.rs

1use bitcoin::Sequence;
2
3use crate::constants::spark::{INITIAL_TIME_LOCK, TIME_LOCK_INTERVAL};
4
5pub(crate) fn initial_sequence() -> Sequence {
6    let sequence = (1 << 30) | INITIAL_TIME_LOCK;
7    Sequence(sequence)
8}
9
10pub(crate) fn next_sequence(curr_sequence: u32) -> u32 {
11    let mask = curr_sequence & 0xFFFF;
12    if TIME_LOCK_INTERVAL >= mask {
13        return 0;
14    };
15
16    (1 << 30) | (mask - TIME_LOCK_INTERVAL)
17}
18
19#[cfg(test)]
20mod next_sequence_tests {
21    use super::*;
22    use crate::constants::spark::TIME_LOCK_INTERVAL;
23
24    #[test]
25    fn test_next_sequence_returns_zero_when_timelock_greater_equal_than_mask() {
26        let sequence = 0;
27        assert_eq!(next_sequence(sequence), 0);
28
29        let curr_sequence = TIME_LOCK_INTERVAL & 0xFFFF;
30        assert_eq!(next_sequence(curr_sequence), 0);
31    }
32
33    #[test]
34    fn test_next_sequence_should_pass_on_minimal_possible_inputs() {
35        assert_eq!(next_sequence(TIME_LOCK_INTERVAL - 1), 0);
36
37        assert_eq!(next_sequence(TIME_LOCK_INTERVAL), 0);
38
39        // *not* equals
40        assert_ne!(next_sequence(TIME_LOCK_INTERVAL + 1), 0);
41    }
42
43    #[test]
44    #[should_panic]
45    fn test_next_sequence_decrements_by_timelock_interval() {
46        let curr_sequence = 100;
47        let expected = (1 << 30) | (100 - TIME_LOCK_INTERVAL);
48        assert_eq!(next_sequence(curr_sequence), expected);
49    }
50
51    #[test]
52    fn test_next_sequence_only_uses_lower_16_bits_of_input() {
53        let curr_sequence = 0xFFFFFFFF;
54        let mask = 0xFFFF;
55        let expected = (1 << 30) | ((mask - TIME_LOCK_INTERVAL) & 0xFFFF);
56        assert_eq!(next_sequence(curr_sequence), expected);
57    }
58}