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