solana_runtime/snapshot_package/
compare.rs

1use {
2    super::{AccountsPackage, AccountsPackageKind, SnapshotKind, SnapshotPackage},
3    std::cmp::Ordering::{self, Equal, Greater, Less},
4};
5
6/// Compare snapshot packages by priority; first by type, then by slot
7#[must_use]
8pub fn cmp_snapshot_packages_by_priority(a: &SnapshotPackage, b: &SnapshotPackage) -> Ordering {
9    cmp_snapshot_kinds_by_priority(&a.snapshot_kind, &b.snapshot_kind).then(a.slot.cmp(&b.slot))
10}
11
12/// Compare accounts packages by priority; first by type, then by slot
13#[must_use]
14pub fn cmp_accounts_packages_by_priority(a: &AccountsPackage, b: &AccountsPackage) -> Ordering {
15    cmp_accounts_package_kinds_by_priority(&a.package_kind, &b.package_kind)
16        .then(a.slot.cmp(&b.slot))
17}
18
19/// Compare accounts package kinds by priority
20///
21/// Priority, from highest to lowest:
22/// - Epoch Accounts Hash
23/// - Full Snapshot
24/// - Incremental Snapshot
25/// - Accounts Hash Verifier
26///
27/// If two `Snapshot`s are compared, their snapshot kinds are the tiebreaker.
28#[must_use]
29pub fn cmp_accounts_package_kinds_by_priority(
30    a: &AccountsPackageKind,
31    b: &AccountsPackageKind,
32) -> Ordering {
33    use AccountsPackageKind as Kind;
34    match (a, b) {
35        // Epoch Accounts Hash packages
36        (Kind::EpochAccountsHash, Kind::EpochAccountsHash) => Equal,
37        (Kind::EpochAccountsHash, _) => Greater,
38        (_, Kind::EpochAccountsHash) => Less,
39
40        // Snapshot packages
41        (Kind::Snapshot(snapshot_kind_a), Kind::Snapshot(snapshot_kind_b)) => {
42            cmp_snapshot_kinds_by_priority(snapshot_kind_a, snapshot_kind_b)
43        }
44        (Kind::Snapshot(_), _) => Greater,
45        (_, Kind::Snapshot(_)) => Less,
46
47        // Accounts Hash Verifier packages
48        (Kind::AccountsHashVerifier, Kind::AccountsHashVerifier) => Equal,
49    }
50}
51
52/// Compare snapshot kinds by priority
53///
54/// Full snapshots are higher in priority than incremental snapshots.
55/// If two `IncrementalSnapshot`s are compared, their base slots are the tiebreaker.
56#[must_use]
57pub fn cmp_snapshot_kinds_by_priority(a: &SnapshotKind, b: &SnapshotKind) -> Ordering {
58    use SnapshotKind as Kind;
59    match (a, b) {
60        (Kind::FullSnapshot, Kind::FullSnapshot) => Equal,
61        (Kind::FullSnapshot, Kind::IncrementalSnapshot(_)) => Greater,
62        (Kind::IncrementalSnapshot(_), Kind::FullSnapshot) => Less,
63        (Kind::IncrementalSnapshot(base_slot_a), Kind::IncrementalSnapshot(base_slot_b)) => {
64            base_slot_a.cmp(base_slot_b)
65        }
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use {super::*, solana_sdk::clock::Slot};
72
73    #[test]
74    fn test_cmp_snapshot_packages_by_priority() {
75        fn new(snapshot_kind: SnapshotKind, slot: Slot) -> SnapshotPackage {
76            SnapshotPackage {
77                snapshot_kind,
78                slot,
79                block_height: slot,
80                ..SnapshotPackage::default_for_tests()
81            }
82        }
83
84        for (snapshot_package_a, snapshot_package_b, expected_result) in [
85            (
86                new(SnapshotKind::FullSnapshot, 11),
87                new(SnapshotKind::FullSnapshot, 22),
88                Less,
89            ),
90            (
91                new(SnapshotKind::FullSnapshot, 22),
92                new(SnapshotKind::FullSnapshot, 22),
93                Equal,
94            ),
95            (
96                new(SnapshotKind::FullSnapshot, 33),
97                new(SnapshotKind::FullSnapshot, 22),
98                Greater,
99            ),
100            (
101                new(SnapshotKind::FullSnapshot, 22),
102                new(SnapshotKind::IncrementalSnapshot(88), 99),
103                Greater,
104            ),
105            (
106                new(SnapshotKind::IncrementalSnapshot(11), 55),
107                new(SnapshotKind::IncrementalSnapshot(22), 55),
108                Less,
109            ),
110            (
111                new(SnapshotKind::IncrementalSnapshot(22), 55),
112                new(SnapshotKind::IncrementalSnapshot(22), 55),
113                Equal,
114            ),
115            (
116                new(SnapshotKind::IncrementalSnapshot(33), 55),
117                new(SnapshotKind::IncrementalSnapshot(22), 55),
118                Greater,
119            ),
120            (
121                new(SnapshotKind::IncrementalSnapshot(22), 44),
122                new(SnapshotKind::IncrementalSnapshot(22), 55),
123                Less,
124            ),
125            (
126                new(SnapshotKind::IncrementalSnapshot(22), 55),
127                new(SnapshotKind::IncrementalSnapshot(22), 55),
128                Equal,
129            ),
130            (
131                new(SnapshotKind::IncrementalSnapshot(22), 66),
132                new(SnapshotKind::IncrementalSnapshot(22), 55),
133                Greater,
134            ),
135        ] {
136            let actual_result =
137                cmp_snapshot_packages_by_priority(&snapshot_package_a, &snapshot_package_b);
138            assert_eq!(expected_result, actual_result);
139        }
140    }
141
142    #[test]
143    fn test_cmp_accounts_packages_by_priority() {
144        fn new(package_kind: AccountsPackageKind, slot: Slot) -> AccountsPackage {
145            AccountsPackage {
146                package_kind,
147                slot,
148                block_height: slot,
149                ..AccountsPackage::default_for_tests()
150            }
151        }
152
153        for (accounts_package_a, accounts_package_b, expected_result) in [
154            (
155                new(AccountsPackageKind::EpochAccountsHash, 11),
156                new(AccountsPackageKind::EpochAccountsHash, 22),
157                Less,
158            ),
159            (
160                new(AccountsPackageKind::EpochAccountsHash, 22),
161                new(AccountsPackageKind::EpochAccountsHash, 22),
162                Equal,
163            ),
164            (
165                new(AccountsPackageKind::EpochAccountsHash, 33),
166                new(AccountsPackageKind::EpochAccountsHash, 22),
167                Greater,
168            ),
169            (
170                new(AccountsPackageKind::EpochAccountsHash, 123),
171                new(
172                    AccountsPackageKind::Snapshot(SnapshotKind::FullSnapshot),
173                    123,
174                ),
175                Greater,
176            ),
177            (
178                new(AccountsPackageKind::EpochAccountsHash, 123),
179                new(
180                    AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(5)),
181                    123,
182                ),
183                Greater,
184            ),
185            (
186                new(AccountsPackageKind::EpochAccountsHash, 123),
187                new(AccountsPackageKind::AccountsHashVerifier, 123),
188                Greater,
189            ),
190            (
191                new(
192                    AccountsPackageKind::Snapshot(SnapshotKind::FullSnapshot),
193                    123,
194                ),
195                new(AccountsPackageKind::EpochAccountsHash, 123),
196                Less,
197            ),
198            (
199                new(
200                    AccountsPackageKind::Snapshot(SnapshotKind::FullSnapshot),
201                    11,
202                ),
203                new(
204                    AccountsPackageKind::Snapshot(SnapshotKind::FullSnapshot),
205                    22,
206                ),
207                Less,
208            ),
209            (
210                new(
211                    AccountsPackageKind::Snapshot(SnapshotKind::FullSnapshot),
212                    22,
213                ),
214                new(
215                    AccountsPackageKind::Snapshot(SnapshotKind::FullSnapshot),
216                    22,
217                ),
218                Equal,
219            ),
220            (
221                new(
222                    AccountsPackageKind::Snapshot(SnapshotKind::FullSnapshot),
223                    33,
224                ),
225                new(
226                    AccountsPackageKind::Snapshot(SnapshotKind::FullSnapshot),
227                    22,
228                ),
229                Greater,
230            ),
231            (
232                new(
233                    AccountsPackageKind::Snapshot(SnapshotKind::FullSnapshot),
234                    123,
235                ),
236                new(
237                    AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(5)),
238                    123,
239                ),
240                Greater,
241            ),
242            (
243                new(
244                    AccountsPackageKind::Snapshot(SnapshotKind::FullSnapshot),
245                    123,
246                ),
247                new(AccountsPackageKind::AccountsHashVerifier, 123),
248                Greater,
249            ),
250            (
251                new(
252                    AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(5)),
253                    123,
254                ),
255                new(AccountsPackageKind::EpochAccountsHash, 123),
256                Less,
257            ),
258            (
259                new(
260                    AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(5)),
261                    123,
262                ),
263                new(
264                    AccountsPackageKind::Snapshot(SnapshotKind::FullSnapshot),
265                    123,
266                ),
267                Less,
268            ),
269            (
270                new(
271                    AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(5)),
272                    123,
273                ),
274                new(
275                    AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(6)),
276                    123,
277                ),
278                Less,
279            ),
280            (
281                new(
282                    AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(5)),
283                    11,
284                ),
285                new(
286                    AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(5)),
287                    22,
288                ),
289                Less,
290            ),
291            (
292                new(
293                    AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(5)),
294                    22,
295                ),
296                new(
297                    AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(5)),
298                    22,
299                ),
300                Equal,
301            ),
302            (
303                new(
304                    AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(5)),
305                    33,
306                ),
307                new(
308                    AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(5)),
309                    22,
310                ),
311                Greater,
312            ),
313            (
314                new(
315                    AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(5)),
316                    123,
317                ),
318                new(
319                    AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(4)),
320                    123,
321                ),
322                Greater,
323            ),
324            (
325                new(
326                    AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(5)),
327                    123,
328                ),
329                new(AccountsPackageKind::AccountsHashVerifier, 123),
330                Greater,
331            ),
332            (
333                new(AccountsPackageKind::AccountsHashVerifier, 11),
334                new(AccountsPackageKind::AccountsHashVerifier, 22),
335                Less,
336            ),
337            (
338                new(AccountsPackageKind::AccountsHashVerifier, 22),
339                new(AccountsPackageKind::AccountsHashVerifier, 22),
340                Equal,
341            ),
342            (
343                new(AccountsPackageKind::AccountsHashVerifier, 33),
344                new(AccountsPackageKind::AccountsHashVerifier, 22),
345                Greater,
346            ),
347        ] {
348            let actual_result =
349                cmp_accounts_packages_by_priority(&accounts_package_a, &accounts_package_b);
350            assert_eq!(expected_result, actual_result);
351        }
352    }
353
354    #[test]
355    fn test_cmp_accounts_package_kinds_by_priority() {
356        for (accounts_package_kind_a, accounts_package_kind_b, expected_result) in [
357            (
358                AccountsPackageKind::EpochAccountsHash,
359                AccountsPackageKind::EpochAccountsHash,
360                Equal,
361            ),
362            (
363                AccountsPackageKind::EpochAccountsHash,
364                AccountsPackageKind::Snapshot(SnapshotKind::FullSnapshot),
365                Greater,
366            ),
367            (
368                AccountsPackageKind::EpochAccountsHash,
369                AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(5)),
370                Greater,
371            ),
372            (
373                AccountsPackageKind::EpochAccountsHash,
374                AccountsPackageKind::AccountsHashVerifier,
375                Greater,
376            ),
377            (
378                AccountsPackageKind::Snapshot(SnapshotKind::FullSnapshot),
379                AccountsPackageKind::EpochAccountsHash,
380                Less,
381            ),
382            (
383                AccountsPackageKind::Snapshot(SnapshotKind::FullSnapshot),
384                AccountsPackageKind::Snapshot(SnapshotKind::FullSnapshot),
385                Equal,
386            ),
387            (
388                AccountsPackageKind::Snapshot(SnapshotKind::FullSnapshot),
389                AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(5)),
390                Greater,
391            ),
392            (
393                AccountsPackageKind::Snapshot(SnapshotKind::FullSnapshot),
394                AccountsPackageKind::AccountsHashVerifier,
395                Greater,
396            ),
397            (
398                AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(5)),
399                AccountsPackageKind::EpochAccountsHash,
400                Less,
401            ),
402            (
403                AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(5)),
404                AccountsPackageKind::Snapshot(SnapshotKind::FullSnapshot),
405                Less,
406            ),
407            (
408                AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(5)),
409                AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(6)),
410                Less,
411            ),
412            (
413                AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(5)),
414                AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(5)),
415                Equal,
416            ),
417            (
418                AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(5)),
419                AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(4)),
420                Greater,
421            ),
422            (
423                AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(5)),
424                AccountsPackageKind::AccountsHashVerifier,
425                Greater,
426            ),
427            (
428                AccountsPackageKind::AccountsHashVerifier,
429                AccountsPackageKind::AccountsHashVerifier,
430                Equal,
431            ),
432        ] {
433            let actual_result = cmp_accounts_package_kinds_by_priority(
434                &accounts_package_kind_a,
435                &accounts_package_kind_b,
436            );
437            assert_eq!(expected_result, actual_result);
438        }
439    }
440
441    #[test]
442    fn test_cmp_snapshot_kinds_by_priority() {
443        for (snapshot_kind_a, snapshot_kind_b, expected_result) in [
444            (
445                SnapshotKind::FullSnapshot,
446                SnapshotKind::FullSnapshot,
447                Equal,
448            ),
449            (
450                SnapshotKind::FullSnapshot,
451                SnapshotKind::IncrementalSnapshot(5),
452                Greater,
453            ),
454            (
455                SnapshotKind::IncrementalSnapshot(5),
456                SnapshotKind::FullSnapshot,
457                Less,
458            ),
459            (
460                SnapshotKind::IncrementalSnapshot(5),
461                SnapshotKind::IncrementalSnapshot(6),
462                Less,
463            ),
464            (
465                SnapshotKind::IncrementalSnapshot(5),
466                SnapshotKind::IncrementalSnapshot(5),
467                Equal,
468            ),
469            (
470                SnapshotKind::IncrementalSnapshot(5),
471                SnapshotKind::IncrementalSnapshot(4),
472                Greater,
473            ),
474        ] {
475            let actual_result = cmp_snapshot_kinds_by_priority(&snapshot_kind_a, &snapshot_kind_b);
476            assert_eq!(expected_result, actual_result);
477        }
478    }
479}