mithril_client/cardano_database_client/
immutable_file_range.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use std::ops::RangeInclusive;

use anyhow::anyhow;

use mithril_common::{entities::ImmutableFileNumber, StdResult};

/// Immutable file range representation
#[derive(Debug)]
pub enum ImmutableFileRange {
    /// From the first (included) to the last immutable file number (included)
    Full,

    /// From a specific immutable file number (included) to the last immutable file number (included)
    From(ImmutableFileNumber),

    /// From a specific immutable file number (included) to another specific immutable file number (included)
    Range(ImmutableFileNumber, ImmutableFileNumber),

    /// From the first immutable file number (included) up to a specific immutable file number (included)
    UpTo(ImmutableFileNumber),
}

impl ImmutableFileRange {
    /// Returns the range of immutable file numbers
    pub fn to_range_inclusive(
        &self,
        last_immutable_file_number: ImmutableFileNumber,
    ) -> StdResult<RangeInclusive<ImmutableFileNumber>> {
        // The immutable file numbers start from 1 on all the networks except the 'devnet'
        // when it is configured with aggressive protocol parameters for fast epochs (used in the e2e tests).
        // We have taken the choice to consider that the file numbers start from 1 for all the networks.
        const FIRST_IMMUTABLE_FILE_NUMBER: ImmutableFileNumber = 1;
        let full_range = FIRST_IMMUTABLE_FILE_NUMBER..=last_immutable_file_number;

        match self {
            ImmutableFileRange::Full => Ok(full_range),
            ImmutableFileRange::From(from) if full_range.contains(from) => {
                Ok(*from..=last_immutable_file_number)
            }
            ImmutableFileRange::Range(from, to)
                if full_range.contains(from)
                    && full_range.contains(to)
                    && !(*from..=*to).is_empty() =>
            {
                Ok(*from..=*to)
            }
            ImmutableFileRange::UpTo(to) if full_range.contains(to) => {
                Ok(FIRST_IMMUTABLE_FILE_NUMBER..=*to)
            }
            _ => Err(anyhow!("Invalid immutable file range: {self:?}")),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn to_range_inclusive_with_full() {
        let immutable_file_range = ImmutableFileRange::Full;
        let last_immutable_file_number = 10;

        let result = immutable_file_range
            .to_range_inclusive(last_immutable_file_number)
            .unwrap();
        assert_eq!(1..=10, result);
    }

    #[test]
    fn to_range_inclusive_with_from() {
        let immutable_file_range = ImmutableFileRange::From(5);

        let last_immutable_file_number = 10;
        let result = immutable_file_range
            .to_range_inclusive(last_immutable_file_number)
            .unwrap();
        assert_eq!(5..=10, result);

        let last_immutable_file_number = 3;
        immutable_file_range
            .to_range_inclusive(last_immutable_file_number)
            .expect_err("should fail: given last immutable should be greater than range start");
    }

    #[test]
    fn to_range_inclusive_with_range() {
        let immutable_file_range = ImmutableFileRange::Range(5, 8);

        let last_immutable_file_number = 10;
        let result = immutable_file_range
            .to_range_inclusive(last_immutable_file_number)
            .unwrap();
        assert_eq!(5..=8, result);

        let last_immutable_file_number = 7;
        immutable_file_range
            .to_range_inclusive(last_immutable_file_number)
            .expect_err(
                "should fail: given last immutable should be greater or equal range max bound",
            );

        let immutable_file_range = ImmutableFileRange::Range(10, 8);
        immutable_file_range
            .to_range_inclusive(last_immutable_file_number)
            .expect_err("should fail: range start should be lower than range end");
    }

    #[test]
    fn to_range_inclusive_with_up_to() {
        let immutable_file_range = ImmutableFileRange::UpTo(8);

        let last_immutable_file_number = 10;
        let result = immutable_file_range
            .to_range_inclusive(last_immutable_file_number)
            .unwrap();
        assert_eq!(1..=8, result);

        let last_immutable_file_number = 7;
        immutable_file_range
            .to_range_inclusive(last_immutable_file_number)
            .expect_err(
                "should fail: given last immutable should be greater or equal range max bound",
            );
    }
}